List comprehensions: Difference between revisions

Remove outdated and no longer supported OCaml solutions
(Remove outdated and no longer supported OCaml solutions)
Line 1,651:
=={{header|OCaml}}==
 
As of OCaml 4.08 (2019), [https://v2.ocaml.org/manual/bindingops.html binding operators] were added to the language syntax. A general notion of "comprehension syntax" can be recovered using them.
[http://batteries.forge.ocamlcore.org/ OCaml Batteries Included] has uniform comprehension syntax for lists, arrays, enumerations (like streams), lazy lists (like lists but evaluated on-demand), sets, hashtables, etc.
 
ComprehensionAssuming area comprehension is of the form
<code>[? expression | x <- enumeration ; condition; condition ; ... ]</code>
We can rewrite it using binding operators like so
<syntaxhighlight lang="ocaml">#let* #camlp4o;;x = enumeration in
if not condition then empty else
return expression
- : int list = [6; 8]</syntaxhighlight>
 
For instance, we can write the required Pythagorean triples comprehension:
For instance,
<syntaxhighlight lang="ocaml"># [? 2 * x | x <- 0 -- max_int ; x * x > 3];;
- : int Enum.t = <abstr></syntaxhighlight>
or, to compute a list,
<syntaxhighlight lang="ocaml"># [? List: 2 * x | x <- 0 -- 100 ; x * x > 3];;
- : int list = [2; 4; 6; 8; 10]</syntaxhighlight>
or, to compute a set,
<syntaxhighlight lang="ocaml"># [? PSet: 2 * x | x <- 0 -- 100 ; x * x > 3];;
- : int PSet.t = <abstr></syntaxhighlight>
 
<syntaxhighlight lang="ocaml">let pyth n =
etc..
let* x = 1 -- n in
let* y = x -- n in
let* z = y -- n in
if x * x + y * y <> z * z then [] else
[x, y, z]
- : int Enum.t = <abstr></syntaxhighlight>
 
where the <code>(let*)</code> and <code>(--)</code> operators are defined for the <code>List</code> module like so:
A standard OCaml distribution also includes a number of camlp4 extensions, including one that provides list comprehensions:
 
<syntaxhighlight lang="ocaml"># #camlp4o;;
<syntaxhighlight lang="ocaml"># [? List: 2let (let*) xxs |f x= <- 0 -- 100 ; x * xList.concat_map >f 3];;xs
# #require "camlp4.listcomprehension";;
let (--) a b = List.init (b-a+1) ((+)a)
/home/user//.opam/4.06.1+trunk+flambda/lib/ocaml/camlp4/Camlp4Parsers/Camlp4ListComprehension.cmo: loaded
- : int PSet.t = <abstr></syntaxhighlight>
# [ x * 2 | x <- [1;2;3;4] ];;
 
- : int list = [2; 4; 6; 8]
=====Historical note=====
# [ x * 2 | x <- [1;2;3;4]; x > 2 ];;
 
- : int list = [6; 8]</syntaxhighlight>
:OCaml never had a built-in list-comprehension syntax. However, there have been a couple of preprocessing syntax extensions which aimed to add list comprehensions sugar to the language. One of which was shipped directly with [https://github.com/camlp4/camlp4 camlp4], a tool for syntax extensions that was bundled with the OCaml compiler distribution, up to version 4.02 (2014), and was completely deprecated after version 4.08 (2019).
 
:Another, [httphttps://batteries.forge.ocamlcoregithub.orgcom/ocaml-batteries-team/batteries-included OCaml Batteries Included], hashad uniform comprehension syntax for lists, arrays, enumerations (like streams), lazy lists (like lists but evaluated on-demand), sets, hashtables, etc. This later split into the now legacy package [https://github.com/murmour/pa_comprehension pa_comprehensions], which is similarly deprecated.
 
=={{header|Oz}}==
13

edits