ocaml-llists / examples / llistcomp_rev.ml

#load "camlp4r.cma" ;;
#load "pa_llistcomp.cma" ;
#load "lazy_list.cmo" ;


open Lazy_list ;



(* Examples from "http://www.haskell.org/haskellwiki/List_comprehension". *)


(* List comprehension may have multiple generators, separated by semicolons. *)
let l = [% (i, j) | i <- [% 1; 2 ]; j <- [% 1 .. 4 ] ]
in to_list l ;
(* - : list (int * int) =
         [(1, 1); (1, 2); (1, 3); (1, 4); (2, 1); (2, 2); (2, 3); (2, 4)] *)


(* Note how each successive generator refines the results of the previous
   generator. Thus, if the second list is infinite, one will never reach the
   second element of the first list. *)
let l = take 10 [% (i, j) | i <- [% 1; 2 ]; j <- [% 1 .. ] ]
in to_list l ;
(* - : list (int * int) =
         [(1, 1); (1, 2); (1, 3); (1, 4); (1, 5);
          (1, 6); (1, 7); (1, 8); (1, 9); (1, 10)] *)


(* In such a situation, a nested sequence of list comprehensions may be appropriate.  *)
let l = take 5 [% to_list [% (i, j) | i <- [% 1; 2] ] | j <- [% 1 .. ] ]
in to_list l ;
(* - : list (list (int * int)) =
         [[(1, 1); (2, 1)]; [(1, 2); (2, 2)]; [(1, 3); (2, 3)];
          [(1, 4); (2, 4)]; [(1, 5); (2, 5)]] *)


(* List comprehension can also provide boolean guards. *)
let rec gcd a = fun
  [ 0 -> a
  | b -> gcd b (a mod b) ]
in
let l = take 10 [% (i, j) | i <- [% 1 .. ]; j <- [% 1 .. i - 1 ]; gcd i j = 1 ]
in to_list l ;
(* - : list (int * int) =
         [(2, 1); (3, 1); (3, 2); (4, 1); (4, 3);
          (5, 1); (5, 2); (5, 3); (5, 4); (6, 1)] *)


(* Finally, it's possible to make local let declaration. *)
let l = take 10 [% (i, j) | i <- [% 1 .. ]; let k = i * i; j <- [% 1 .. k ] ]
in to_list l ;
(* - : list (int * int) =
         [(1, 1); (2, 1); (2, 2); (2, 3); (2, 4);
          (3, 1); (3, 2); (3, 3); (3, 4); (3, 5)] *)



(* Some more examples. *)

let l = [% (x, y, z) | x <- [% 1 .. 20 ]; y <- [% x .. 20 ];
                       z <- [% y .. 20 ]; x * x + y * y = z * z]
in to_list l ;
(* - : list (int * int * int) =
         [(3, 4, 5); (5, 12, 13); (6, 8, 10);
          (8, 15, 17); (9, 12, 15); (12, 16, 20)] *)


let l = [% x | xs <- [% [% (1, 2); (3, 4) ]; [% (5, 4); (3, 2) ] ];
               (3, x) <- xs ]
in to_list l ;
(* - : list int = [4; 2] *)


let l = take 5 [% (i, j, l) | i <- [% 1 ..]; let k = i * i; let j = k * k;
                              i > 2; i < 10; l <- [% 0; 1 ] ]
in to_list l ;
(* - : list (int * int * int) =
         [(3, 81, 0); (3, 81, 1); (4, 256, 0); (4, 256, 1); (5, 625, 0)] *)

let l = take 5 [% (i, j, l) | i <- [% 1 ..]; i > 2; i < 10;
                              let k = i * i; let j = k * k; l <- [% 0; 1 ] ]
in to_list l ;
(* - : list (int * int * int) =
         [(3, 81, 0); (3, 81, 1); (4, 256, 0); (4, 256, 1); (5, 625, 0)] *)

let l = take 5 [% (i, j, l) | i <- [% 1 ..]; i > 2; i < 10;
                              let k = i * i and j = i * i * i * i;
                              l <- [% 0; 1 ] ]
in to_list l ;
(* Warning Y: unused variable k.
   - : list (int * int * int) =
     [(3, 81, 0); (3, 81, 1); (4, 256, 0); (4, 256, 1); (5, 625, 0)] *)


let l = take 5 [% (i, k) | i <- [% 1 ..];
                           let k = i * i; let j = k * k in i < 10 ]
in to_list l ;
(* Warning Y: unused variable j.
   - : list (int * int) = [(1, 1); (2, 4); (3, 9); (4, 16); (5, 25)] *)


let l = take 5 [% (i, l) | i <- [% 1 ..]; let (k, l) = (i * i, i * i * i);
                         let z = 1 in k > 1 ]
in to_list l ;
(* Warning Y: unused variable z.
   - : list (int * int) = [(2, 8); (3, 27); (4, 64); (5, 125); (6, 216)] *)

let l = take 5 [% (i, l) | i <- [% 1 ..]; let (k, l) = (i * i, i * i * i);
                           l <- [% k .. l ]; let (x, z) = (1, 2) in k > 1 ]
in to_list l ;
(* Warning Y: unused variable z.
   Warning Y: unused variable x.
   - : list (int * int) = [(2, 4); (2, 5); (2, 6); (2, 7); (2, 8)] *)

let l = take 5 [% (i, l) | i <- [% 1 ..]; let (k, l) = (i * i, i * i * i);
                           let (l, k) = (1, 2) in k > 1 ]
in to_list l ;
(* - : list (int * int) = [(1, 1); (2, 8); (3, 27); (4, 64); (5, 125)] *)


let primes =
  let rec sieve = fun
    [ [% hd :: tl ] -> [% hd :: sieve [% x | x <- tl; x mod hd > 0 ] ] ]
  in [% 2 :: sieve [% 3; 5 .. ] ]
in to_list (take 20 primes) ;
(* Warning P: this pattern-matching is not exhaustive.
   Here is an example of a value that is not matched:
   Nil
   - : list int =
         [2; 3; 5; 7; 11; 13; 17; 19; 23; 29; 31;
          37; 41; 43; 47; 53; 59; 61; 67; 71] *)


let l = take 5 [% (i, fact i) | i <- [% 1 .. ];
                                let rec fact = fun [ 0 -> 1
                                                   | n -> n * fact (n - 1) ] ]
in to_list l ;
(* - : list (int * int) = [(1, 1); (2, 2); (3, 6); (4, 24); (5, 120)] *)

let l = take 5 [% (i, j) | i <- [% 1 .. ];
                           let rec fact = ( fun [ 0 -> 1
                                                | n -> n * fact (n - 1) ] );
                           let j = fact i ]
in to_list l ;
(* - : list (int * int) = [(1, 1); (2, 2); (3, 6); (4, 24); (5, 120)] *)



(* Parallel lazy list comprehension. *)

(* http://www.haskell.org/ghc/docs/latest/html/users_guide/syntax-extns.html#parallel-list-comprehensions *)


let l = [% (x, y) | x <- [% 1; 3 .. 9 ] | y <- [% 2; 4 .. 10 ] ]
in to_list l ;
(* - : list (int * int) = [(1, 2); (3, 4); (5, 6); (7, 8); (9, 10)] *)

let l = [% (x, y) | x <- [% 1; 3 .. ] | y <- [% 2; 4 .. 10 ] ]
in to_list l ;
(* - : list (int * int) = [(1, 2); (3, 4); (5, 6); (7, 8); (9, 10)] *)
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.