94 lines
2.6 KiB
JavaScript
94 lines
2.6 KiB
JavaScript
(() => {
|
|
'use strict';
|
|
|
|
// COMMA QUIBBLING -------------------------------------------------------
|
|
|
|
// quibble :: [String] -> String
|
|
const quibble = xs =>
|
|
(xs.length > 1) ? (
|
|
intercalate(
|
|
" and ",
|
|
ap(
|
|
[compose([intercalate(", "), reverse, tail]), head], //
|
|
[reverse(xs)]
|
|
)
|
|
)
|
|
) : concat(xs);
|
|
|
|
|
|
// GENERIC FUNCTIONS -----------------------------------------------------
|
|
|
|
// A list of functions applied to a list of arguments
|
|
// <*> :: [(a -> b)] -> [a] -> [b]
|
|
const ap = (fs, xs) => //
|
|
[].concat.apply([], fs.map(f => //
|
|
[].concat.apply([], xs.map(x => [f(x)]))));
|
|
|
|
// curry :: Function -> Function
|
|
const curry = (f, ...args) => {
|
|
const go = xs => xs.length >= f.length ? (f.apply(null, xs)) :
|
|
function () {
|
|
return go(xs.concat([].slice.apply(arguments)));
|
|
};
|
|
return go([].slice.call(args, 1));
|
|
};
|
|
|
|
// intercalate :: String -> [a] -> String
|
|
const intercalate = curry((s, xs) => xs.join(s));
|
|
|
|
// concat :: [[a]] -> [a] | [String] -> String
|
|
const concat = xs => {
|
|
if (xs.length > 0) {
|
|
const unit = typeof xs[0] === 'string' ? '' : [];
|
|
return unit.concat.apply(unit, xs);
|
|
} else return [];
|
|
};
|
|
|
|
// compose :: [(a -> a)] -> (a -> a)
|
|
const compose = fs => x => fs.reduceRight((a, f) => f(a), x);
|
|
|
|
// map :: (a -> b) -> [a] -> [b]
|
|
const map = curry((f, xs) => xs.map(f));
|
|
|
|
// reverse :: [a] -> [a]
|
|
const reverse = xs =>
|
|
typeof xs === 'string' ? (
|
|
xs.split('')
|
|
.reverse()
|
|
.join('')
|
|
) : xs.slice(0)
|
|
.reverse();
|
|
|
|
// head :: [a] -> a
|
|
const head = xs => xs.length ? xs[0] : undefined;
|
|
|
|
// tail :: [a] -> [a]
|
|
const tail = xs => xs.length ? xs.slice(1) : undefined;
|
|
|
|
// (++) :: [a] -> [a] -> [a]
|
|
const append = (xs, ys) => xs.concat(ys);
|
|
|
|
// words :: String -> [String]
|
|
const words = s => s.split(/\s+/);
|
|
|
|
// unlines :: [String] -> String
|
|
const unlines = xs => xs.join('\n');
|
|
|
|
|
|
// TEST ------------------------------------------------------------------
|
|
return unlines(
|
|
map(
|
|
compose([x => '{' + x + '}', quibble]),
|
|
append([
|
|
[],
|
|
["ABC"],
|
|
["ABC", "DEF"],
|
|
["ABC", "DEF", "G", "H"]
|
|
], map(
|
|
words, [
|
|
"One two three four", "Me myself I", "Jack Jill", "Loner"
|
|
]
|
|
))
|
|
));
|
|
})();
|