Diving into Batteries #1 : Comprehension

Hi,

I’m back here to introduce a very promising project : OCaml Batteries Included.

It aims at putting together all the things we may need as OCaml developers in a standard library. It has already put together some existing modules (Extlib, etc) and is now growing up with totally new modules.

The first thing you have to know is that with such standardization efforts, the aim is really to get OCaml programming funnier and easier, with strong and efficient modules helping us in everyday-programming. Moreover, there are some syntax extensions that were really missing in OCaml like the one I’m going to tell about : Comprehension.

What is Comprehension ?

You may probably know better expressions like “List comprehension” ? In fact, OCaml Batteries Included (also called Batteries) provide us something more general than List comprehensions. The aim of such techniques is to, given an expression, a “data domain” and, if wanted, constraints, expand the expression to a set (not in its mathematical sense) of data of the form of the given expression, based on elements that belong to their respective domains and respect their respective constraints. It uses by default an Enum interface for building comprehension of any data container that provide some precise functions. Python or Haskell developers, e.g, may be used to List comprehension. It lets us write such codes, in Haskell :

?View Code HASKELL
1
[ x*2 | x <- [1,2,3,4,5,6,7,8,9,10] ]
?View Code HASKELL
1
[ x*x + 1 | x <- [1..100] ]
?View Code HASKELL
1
[ x*y - x - y | x <- [1..100] , y <- [1..100] , x+y < 40 ]

Now, it is possible in OCaml using Batteries to write such code, in a very similar way :

1
[? x*2 | x <- List : [1;2;3;4;5;6;7;8;9;10] ]
1
[? x*x + 1 | x <- 1--100 ]
1
[? x*y - x - y | x <- 1--100 ; y <- 1--100; x+y < 40 ]

We can achieve such work on Lists, Arrays, Lazy Lists, …

Moreover, we can specify the container type we want to get after the “comprehension”, as we can see in the documentation of Batteries :

1
2
let positive_array_of_enum e =
  [? Array : n | n <- e; n > 0 ]

In fact, the most powerful feature of the comprehension feature in OCaml Batteries Included is that it relies only on the presence of some functions in the data container module :

1
2
3
4
5
6
7
val filter : ('a -> bool) -> 'a t -> 'a t
val concat : 'a t t -> 'a t
val map : ('a -> 'b) -> 'a t -> 'b t
val filter_map : ('a -> 'b option) -> 'a t -> 'b t (* used for refutable patterns in generators *)
 
val enum : 'a t -> 'a Enum.t
val of_enum : 'a Enum.t -> 'a t

where ‘a is the type of the values you are enumerating, and ‘a t is the data container type : ‘a array, ‘a Enum.t, ‘a list, etc.

However, providing only enum and of_enum will let you work quite well (but not perfectly) with the comprehension extension, interacting with the Enum module.

I hope this feature has caught your interest.

Here are some links about OCaml Batteries Included and this Comprehension feature.
OCaml Batteries Included’s page on OCamlCore.org
The syntax extensions page of Batteries, including some details about Comprehension
Batteries’ install guide

This project is a community project, so I adress thanks to all the contributors of Batteries, but special thanks go to David Teller for his leading and huge participation on OCaml Batteries Included, and to Gabriel Scherer for his participation and for telling me about this project. And, of course, any contribution to this project is welcome.


Leave a Comment