🌱 Permutations in JS
https://www.baeldung.com/cs/array-generate-all-permutations
https://medium.com/javascript-in-plain-english/how-to-solve-permutations-in-javascript-502cc4522482
https://rosettacode.org/wiki/Permutations_with_repetitions#ES6
'use strict'
// GENERIC FUNCTIONS
// replicateM n act performs the action n times, gathering the results.
// replicateM :: (Applicative m) => Int -> m a -> m [a]
const replicateM = (n, f) => {
const loop = (x) => (x <= 0 ? [[]] : liftA2(cons, f, loop(x - 1)))
return loop(n)
}
// Lift a binary function to actions.
// liftA2 :: Applicative f => (a -> b -> c) -> f a -> f b -> f c
const liftA2 = (f, a, b) => listApply(a.map(curry(f)), b)
// <*>
// listApply :: [(a -> b)] -> [a] -> [b]
const listApply = (fs, xs) =>
[].concat.apply(
[],
fs.map((f) =>
[].concat.apply(
[],
xs.map((x) => [f(x)])
)
)
)
// curry :: ((a, b) -> c) -> a -> b -> c
const curry = (f) => (a) => (b) => f(a, b)
// cons :: a -> [a] -> [a]
const cons = (x, xs) => [x].concat(xs)
// show :: a -> String;
const show = JSON.stringify
// TEST
console.log(show(replicateM(8, [0, 1])))