Cartesian product of two or more lists: Difference between revisions

Content added Content deleted
m (→‎{{header|OCaml}}: remove excess whitespace)
Line 1,895:
''The double semicolons are necessary only for the toplevel''
 
Naive but more readable version<lang ocaml>let rec product l1 l2 =
<lang ocaml>
let rec product l1 l2 =
match l1, l2 with
| [], _ | _, [] -> []
Line 1,910 ⟶ 1,908:
(*- : (int * 'a) list = []*)
product [] [1;2];;
(*- : ('a * int) list = []*)</lang>
</lang>
 
Implementation with a bit more tail-call optimization, inroducing a helper function. The order of the result is changed but it should not be an issue for most uses.
<lang ocaml>let product' l1 l2 =
let product' l1 l2 =
let rec aux ~acc l1' l2' =
match l1', l2' with
Line 1,933 ⟶ 1,929:
(*- : (int * 'a) list = []*)
product' [] [1;2];;
(*- : ('a * int) list = []*)</lang>
</lang>
Implemented using nested folds:
<lang ocaml>let cart_prod l1 l2 =
let cart_prod l1 l2 =
List.fold_left (fun acc1 ele1 ->
List.fold_left (fun acc2 ele2 -> (ele1,ele2)::acc2) acc1 l2) [] l1 ;;
Line 1,944 ⟶ 1,938:
(*- : (int * char) list = [(3, 'c'); (3, 'b'); (3, 'a'); (2, 'c'); (2, 'b'); (2, 'a'); (1, 'c'); (1, 'b'); (1, 'a')]*)
cart_prod [1; 2; 3] [] ;;
(*- : ('a * int) list = [] *)</lang>
</lang>
 
Extra credit function. Since in OCaml a function can return only one type, and because tuples of different arities are different types, this returns a list of lists rather than a list of tuples.
<lang ocaml>let rec product'' l =
let rec product'' l =
(* We need to do the cross product of our current list and all the others
* so we define a helper function for that *)
Line 1,994 ⟶ 1,986:
*)
product'' [[1; 2; 3];[];[500; 100]];;
(*- : int list list = []*)</lang>
 
</lang>
 
=== Better type ===
 
In the latter example, our function has this signature:
<lang ocaml>val product'' : 'a list list -> 'a list list = <fun></lang>
<lang ocaml>
val product'' : 'a list list -> 'a list list = <fun>
</lang>
This lacks clarity as those two lists are not equivalent since one replaces a tuple. We can get a better signature by creating a tuple type:
<lang ocaml>type 'a tuple = 'a list
type 'a tuple = 'a list
 
let rec product'' (l:'a list tuple) =
Line 2,027 ⟶ 2,014:
 
type 'a tuple = 'a list
val product'' : 'a list tuple -> 'a tuple list = <fun></lang>
</lang>
 
=={{header|Perl}}==