List comprehension in OCaml
A nifty thing when working with list is to use list comprehension. This is something natural for a python programmer :
l1 = [(1,2),(2,3),(3,4),(4,5),(5,6),(6,7)]
# [(1, 2), (2, 3), (3, 4), (4, 5), (5, 6), (6, 7)]
l2 = [2*x+y for (x,y) in l1]
# [4, 7, 10, 13, 16, 19]
l3 = [x for x in l2 if x > 12]
# [13, 16, 19]
# [(1, 2), (2, 3), (3, 4), (4, 5), (5, 6), (6, 7)]
l2 = [2*x+y for (x,y) in l1]
# [4, 7, 10, 13, 16, 19]
l3 = [x for x in l2 if x > 12]
# [13, 16, 19]
It is however absent from OCaml… Of course, it can be emulated:
let l1 = [1,2;2,3;3,4;4,5;5,6;6,7] in
let l2 = (fun fmap l -> List.rev_map fmap (List.rev l)) (fun (x,y) -> 2*x+y) l1 in
let l3 = (fun ffilt fmap l ->
let rev_filter f l =
let rec aux d = fun
[ [] -> d
| [t::q] -> aux (if f t then [t::d] else d) q]
in
aux [] l
in
List.rev_map fmap (rev_filter ffilt l)) (fun x -> x > 12) (fun x -> x) l2
in ()
let l2 = (fun fmap l -> List.rev_map fmap (List.rev l)) (fun (x,y) -> 2*x+y) l1 in
let l3 = (fun ffilt fmap l ->
let rev_filter f l =
let rec aux d = fun
[ [] -> d
| [t::q] -> aux (if f t then [t::d] else d) q]
in
aux [] l
in
List.rev_map fmap (rev_filter ffilt l)) (fun x -> x > 12) (fun x -> x) l2
in ()
But this is really too much… Wouldn't it be nice to write something like that :
let l1 = [1,2;2,3;3,4;4,5;5,6;6,7] in
let l2 = [+ 2*x+y | (x,y) <- l1] in
let l3 = [+ x | x <- l2 when x > 12] in
()
let l2 = [+ 2*x+y | (x,y) <- l1] in
let l3 = [+ x | x <- l2 when x > 12] in
()
The [+ (* ... *)] indicates that this is a list comprehension. This actually is possible using camlp4