Cartesian product of two or more lists: Difference between revisions

Content added Content deleted
(→‎Functional JS: Updated applicative version)
Line 1,114: Line 1,114:




Even more economically, we can define the cartesian product in terms of an applicative operator:
Abstracting a little more, we can define the cartesian product quite economically in terms of a general applicative operator:
<lang Javascript>(() => {
<lang Javascript>(() => {


// CARTESIAN PRODUCT OF TWO LISTS -----------------------------------------
// CARTESIAN PRODUCT OF TWO LISTS ---------------------


// cartesianProduct :: [a] -> [b] -> [(a, b)]
// cartesianProduct :: [a] -> [b] -> [(a, b)]
const cartesianProduct = (xs, ys) =>
const cartesianProduct = xs =>
ap(xs.map(x => y => [x, y]), ys);
ap(xs.map(Tuple));




// GENERIC FUNCTIONS ------------------------------------------------------
// GENERIC FUNCTIONS ----------------------------------


// e.g. [(*2),(/2), sqrt] <*> [1,2,3]
// e.g. [(*2),(/2), sqrt] <*> [1,2,3]
Line 1,134: Line 1,134:


// ap (<*>) :: [(a -> b)] -> [a] -> [b]
// ap (<*>) :: [(a -> b)] -> [a] -> [b]
const ap = (fs, xs) => //
const ap = fs => xs =>
// The sequential application of each of a list
fs.reduce((a, f) => a.concat(
xs.reduce((a, x) => a.concat([f(x)]), [])
// of functions to each of a list of values.
), []);
fs.flatMap(
f => xs.map(f)
);


// Tuple (,) :: a -> b -> (a, b)
// TEST -------------------------------------------------------------------
const Tuple = a => b => [a, b];

// TEST -----------------------------------------------
return [
return [
cartesianProduct([1, 2], [3, 4]),
cartesianProduct([1, 2])([3, 4]),
cartesianProduct([3, 4], [1, 2]),
cartesianProduct([3, 4])([1, 2]),
cartesianProduct([1, 2], []),
cartesianProduct([1, 2])([]),
cartesianProduct([], [1, 2]),
cartesianProduct([])([1, 2]),
]
]
.map(JSON.stringify)
.map(JSON.stringify)