Skip to content

Instantly share code, notes, and snippets.

@bas080
Created April 24, 2018 20:38
Show Gist options
  • Save bas080/818f1002d60276fd4ecc5f505ee2ab8d to your computer and use it in GitHub Desktop.
Save bas080/818f1002d60276fd4ecc5f505ee2ab8d to your computer and use it in GitHub Desktop.
function next(current = []) {
if (current.length === 0)
return [1]
if (current.length === 1)
return [1, 1]
return [1, ...nextIter(current), 1]
}
function nextIter(items, acc = []) {
if (items.length === 1)
return acc
const [first, second, ...rest] = items
return nextIter(
[second, ...rest],
[...acc, sum(first, second)]
)
}
function sum(a, b) {
return a + b
}
function times(fn, n) {
if (n === 0)
return [fn(n)]
return [...times(fn, n - 1), fn(n)]
}
function pascal(rows = 10) {
let value = []
return times(n => {
value = next(value)
return value
}, rows)
}
console.log(pascal(5))
function isDivisibleBy(n) {
return value => (value % n) === 0 && value !== 0
}
function and(predA, predB) {
return (...args) => predA(...args) && predB(...args)
}
const always = v => () => v
const isNil = v => v == null
const isDivisibleByThree = isDivisibleBy(3)
const isDivisibleByFive = isDivisibleBy(5)
const isDivisibleByThreeAndFive = and(isDivisibleByThree, isDivisibleByFive)
function cond([pred, fn, ...cases]) {
if (isNil(pred))
return always(undefined)
return (...args) =>
pred(...args)
? fn(...args)
: cond(cases)(...args)
}
const otherwise = () => true
const identity = v => v
const fizzBuzz = cond([
isDivisibleByThreeAndFive, always('FizzBuzz'),
isDivisibleByThree, always('Fizz'),
isDivisibleByFive, always('Buzz'),
otherwise, identity,
])
console.log(times(fizzBuzz, 24))
// transducers
const filterer = fn => reducer =>
(acc, value) => fn(value)
? reducer(acc, value)
: acc
const mapper = fn => reducer =>
(acc, value) => reducer(acc, fn(value))
const reducer = (fn, seed) => _ => {
let first = true
return (acc, value) => {
if (first) {
first = false
return fn(seed, value)
}
return fn(acc, value)
}
}
const append = (acc, item) => [...acc, item]
function transduce(transducer, init, list) {
return list.reduce(transducer(append), init)
}
function pipe(fn, ...fns) {
if (isNil(fn))
return identity
return (...args) => {
return pipe(...fns)(fn(...args))
}
}
function compose(...fns) {
return pipe(...reverse(fns))
}
function reverse([v, ...items], reversed = []) {
return isNil(v)
? reversed
: reverse(items, [v, ...reversed])
}
function inc(n) {
return n + 1
}
function isOdd(n) {
return n % 2 === 1
}
function partial(fn, ...args) {
return (...more) => fn(...[...args, ...more])
}
console.log(
transduce(
compose(
filterer(isOdd),
mapper(inc),
reducer(sum, 0)
),
[],
times(identity, 50)
)
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment