Syntax extensions

thelema edited this page Sep 29, 2011 · 2 revisions

Batteries provides syntax extensions for List comprehensions and Enhanced string literals.

List Comprehensions

Output, generators and guards

The global form is [? output | comp_item ; comp_item ; ... ?]. output is an expression and a comp_item is either a guard (a boolean expression), or a generator of the form pattern <- expression. Variables bound in the pattern can be used in the following comprehension items, and in the output expression. Example :

let pythagorean_triples n =
  [? (a,b,c) | a <- 1--n; b <- a--n; c <- b--n; a*a + b*b = c*c ?]

Module parametrization

By default, the output in an enumeration ('a Enum.t), and generator expressions are assumed to be enumerations. It is possible to choose a different data structure with the module : expression syntax. Examples :

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

let combine la lb =
  [? List : (a, b) | a <- List : la; b <- List : lb ?]

Comprehension expressions rely on the presence in the given module of the following operations (where 'a t represents the data-structure type : 'a array, 'a Enum.t...) :

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

If your module does not provide the first four operations but only the enum conversion functions, you could still benefit from the comprehension syntax by using eg. foo <- Mod.enum bar instead of foo <- Mod : bar.

Enhanced String Literals

Text Values

Declaring a Rope is as simple as

let foo = r"Some Unicode text (Latin-1 encoded)"
let bar = ur"Some Unicode text (UTF-8 encoded)"

This defines a new value foo, with type Rope.t, the type of (immutable) Unicode ropes. Of course, this manipulation doesn't have to happen at the highest-level:

let append_string_to_rope x = Rope.append x (r"Some more Unicode text")

Note that ropes, being immutable, are automatically optimized, i.e. this is equivalent to

let some_unique_name = Rope.of_latin1 "Some more Unicode text"
let append_string_to_rope x = Rope.append x some_unique_name

It is possible to use the same syntax to define

Mutable UTF-8 strings: u"Some UTF-8 string", with type UTF8.t

Immutable Latin 1 strings (with capabilities): ro"Some read-only string", with type [`Read] String.Cap.t

Mutable Latin 1 strings (with capabilities): rw"Some read-write string", with type [`Read | `Write] String.Cap.t

Write-only Latin 1 strings (with capabilities): wo"Some write-only string", with type [`Write] String.Cap.t

Again, immutable latin-1 strings are automatically optimized.

##Text patterns The same syntax may be used to pattern-match against ropes, UTF-8 strings and string with capabilities.