RosettaCodeData/Task/Catalan-numbers/JavaScript/catalan-numbers-2.js

86 lines
1.8 KiB
JavaScript

(() => {
"use strict";
// ----------------- CATALAN NUMBERS -----------------
// catalansDefinitionThree :: [Int]
const catalansDefinitionThree = () =>
// An infinite sequence of Catalan numbers.
scanlGen(
c => n => Math.floor(
(2 * c * pred(2 * n)) / succ(n)
)
)(1)(
enumFrom(1)
);
// ---------------------- TEST -----------------------
// main :: IO ()
const main = () =>
take(15)(
catalansDefinitionThree()
);
// --------------------- GENERIC ---------------------
// enumFrom :: Enum a => a -> [a]
const enumFrom = function* (n) {
// An infinite sequence of integers,
// starting with n.
let v = n;
while (true) {
yield v;
v = 1 + v;
}
};
// pred :: Int -> Int
const pred = x =>
x - 1;
// scanlGen :: (b -> a -> b) -> b -> Gen [a] -> [b]
const scanlGen = f =>
// The series of interim values arising
// from a catamorphism over an infinite list.
startValue => function* (gen) {
let
a = startValue,
x = gen.next();
yield a;
while (!x.done) {
a = f(a)(x.value);
yield a;
x = gen.next();
}
};
// succ :: Int -> Int
const succ = x =>
1 + x;
// take :: Int -> [a] -> [a]
// take :: Int -> String -> String
const take = n =>
// The first n elements of a list,
// string of characters, or stream.
xs => Array.from({
length: n
}, () => {
const x = xs.next();
return x.done ? [] : [x.value];
}).flat();
// MAIN ---
return JSON.stringify(main(), null, 2);
})();