Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Question about OCaml's list Comprehensions

646 views
Skip to first unread message

Kecheng

unread,
Jun 2, 2008, 6:48:47 PM6/2/08
to comp-l...@moderators.isc.org
Are there some built-in like it in Haskell to generate and manipulate
list like this in OCaml?
Mant Thanks
Generators
Main> [1..10]
[1,2,3,4,5,6,7,8,9,10]
Manipulators
Main> [ i * 2 | i <- [2..8]]
[4,6,8,10,12,14,16]

Neelakantan Krishnaswami

unread,
Jun 3, 2008, 7:33:06 PM6/3/08
to comp-l...@moderators.isc.org
In article <<mailman.5.1212466881.9...@mailman.srv.cs.cmu.edu>>,

Kecheng <keche...@gmail.com> wrote:
> Are there some built-in like it in Haskell to generate and manipulate
> list like this in OCaml?

Nothing built-in, but you can define higher-order functions to do
these operations.

> Mant Thanks
> Generators
> Main> [1..10]
> [1,2,3,4,5,6,7,8,9,10]

let rec range i j = if i < j then [] else i :: (range (i+1) j)

# range 1 10;;
- : int list = [1; 2; 3; 4; 5; 6; 7; 8; 9; 10]


> Manipulators
> Main> [ i * 2 | i <- [2..8]]
> [4,6,8,10,12,14,16]

let (>>) lst f = List.concat (List.map f lst)
let one x = [x]

# range 2 8 >> (fun i -> one (i * 2));;
- : int list = [4; 6; 8; 10; 12; 14; 16]

You can also define guards and cross products like this:

let guard b e = if b then e else []

# range 1 6 >> (fun x ->
range 1 6 >> (fun y ->
guard (x > y) (one (x,y))));;

- : int list = [(2, 1);
(3, 1); (3, 2);
(4, 1); (4, 2); (4, 3);
(5, 1); (5, 2); (5, 3); (5, 4);
(6, 1); (6, 2); (6, 3); (6, 4); (6, 5)]

Assuming I got the syntax right, this is equivalent to:

[ (x, y) | x <- [1..6],
y <- [1..6],
x > y]

--
Neel R. Krishnaswami
ne...@cs.cmu.edu

Eric Jaeger

unread,
Jun 4, 2008, 7:12:47 PM6/4/08
to sml-...@cs.cmu.edu

What for ? Try

let l1=let rec f n=if n<=10 then n::f (n+1) else [] in f 1;;
let l2=let rec f n=if n<=8 then (2*n)::f (n+1) else [] in f 2;;

Now I don't know Haskell, so I'm not sure of how [1..10] works ; is it a
constant evaluated at compilation time to allow e.g. a form of pattern
matching ? Or is it just a notation trick to call a function of the form
"let l st ed step=let rec f n=if n<=ed then (n*step)::f (n+1) else [] in f
st;;" ?

Regards, Eric


Christoph Bauer

unread,
Jun 5, 2008, 2:49:43 PM6/5/08
to comp-l...@moderators.isc.org

>> Main> [1..10]
>> [1,2,3,4,5,6,7,8,9,10]
>
> let rec range i j = if i < j then [] else i :: (range (i+1) j)
>
> # range 1 10;;
> - : int list = [1; 2; 3; 4; 5; 6; 7; 8; 9; 10]

really? try is again!

>> Manipulators
>> Main> [ i * 2 | i <- [2..8]]
>> [4,6,8,10,12,14,16]

In OCaml you could do:

$ ocaml
# #load "camlp4o.cma";;
Camlp4 Parsing version 3.10.2

# #load "Camlp4Parsers/Camlp4ListComprehension.cmo";;
# let rec range i j = if i > j then [] else i :: range (i+1) j;;
val range : int -> int -> int list = <fun>
# [ i * 2 | i <- range 2 8 ];;


- : int list = [4; 6; 8; 10; 12; 14; 16]

#

Christoph Bauer

Torben Ægidius Mogensen

unread,
Jun 5, 2008, 4:17:00 AM6/5/08
to comp-l...@moderators.isc.org
"Eric Jaeger" <eric.jae...@noos.fr> writes:

> Now I don't know Haskell, so I'm not sure of how [1..10] works ; is it
> a constant evaluated at compilation time to allow e.g. a form of
> pattern matching ? Or is it just a notation trick to call a function
> of the form "let l st ed step=let rec f n=if n<=ed then (n*step)::f
> (n+1) else [] in f st;;" ?

The latter, though later steps of the compilation might unfold these
calls. Haskell also supports intervals of the form [1..], which
obviously can not be evaluated to constants at compile time.

List comprehensions are in the Glasgow Haskell compiler compiled using
shortcut deforestation, which means that many of the intermediate
lists that a straightforward translation might generate are
eliminated.

Torben

0 new messages