93 lines
2.4 KiB
JavaScript
93 lines
2.4 KiB
JavaScript
(() => {
|
|
'use strict';
|
|
|
|
// leo :: Int -> Int -> Int -> Generator [Int]
|
|
function* leo(L0, L1, delta) {
|
|
let [x, y] = [L0, L1];
|
|
while (true) {
|
|
yield x;
|
|
[x, y] = [y, delta + x + y];
|
|
}
|
|
}
|
|
|
|
// ----------------------- TEST ------------------------
|
|
// main :: IO ()
|
|
const main = () => {
|
|
const
|
|
leonardo = leo(1, 1, 1),
|
|
fibonacci = leo(0, 1, 0);
|
|
|
|
return unlines([
|
|
'First 25 Leonardo numbers:',
|
|
indentWrapped(take(25)(leonardo)),
|
|
'',
|
|
'First 25 Fibonacci numbers:',
|
|
indentWrapped(take(25)(fibonacci))
|
|
]);
|
|
};
|
|
|
|
// -------------------- FORMATTING ---------------------
|
|
|
|
// indentWrapped :: [Int] -> String
|
|
const indentWrapped = xs =>
|
|
unlines(
|
|
map(x => '\t' + x.join(','))(
|
|
chunksOf(16)(
|
|
map(str)(xs)
|
|
)
|
|
)
|
|
);
|
|
|
|
// ----------------- GENERIC FUNCTIONS -----------------
|
|
|
|
// chunksOf :: Int -> [a] -> [[a]]
|
|
const chunksOf = n =>
|
|
xs => enumFromThenTo(0)(n)(
|
|
xs.length - 1
|
|
).reduce(
|
|
(a, i) => a.concat([xs.slice(i, (n + i))]),
|
|
[]
|
|
);
|
|
|
|
// enumFromThenTo :: Int -> Int -> Int -> [Int]
|
|
const enumFromThenTo = x1 =>
|
|
x2 => y => {
|
|
const d = x2 - x1;
|
|
return Array.from({
|
|
length: Math.floor(y - x2) / d + 2
|
|
}, (_, i) => x1 + (d * i));
|
|
};
|
|
|
|
// map :: (a -> b) -> [a] -> [b]
|
|
const map = f =>
|
|
// The list obtained by applying f
|
|
// to each element of xs.
|
|
// (The image of xs under f).
|
|
xs => [...xs].map(f);
|
|
|
|
// str :: a -> String
|
|
const str = x =>
|
|
x.toString();
|
|
|
|
// take :: Int -> [a] -> [a]
|
|
// take :: Int -> String -> String
|
|
const take = n =>
|
|
// The first n elements of a list,
|
|
// string of characters, or stream.
|
|
xs => 'GeneratorFunction' !== xs
|
|
.constructor.constructor.name ? (
|
|
xs.slice(0, n)
|
|
) : [].concat.apply([], Array.from({
|
|
length: n
|
|
}, () => {
|
|
const x = xs.next();
|
|
return x.done ? [] : [x.value];
|
|
}));
|
|
|
|
// unlines :: [String] -> String
|
|
const unlines = xs => xs.join('\n');
|
|
|
|
// MAIN ---
|
|
return main();
|
|
})();
|