Skip to content

Instantly share code, notes, and snippets.

@wl00887404
Last active January 1, 2018 06:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save wl00887404/701d2e674babade309dc9d3259ad10b1 to your computer and use it in GitHub Desktop.
Save wl00887404/701d2e674babade309dc9d3259ad10b1 to your computer and use it in GitHub Desktop.
const head = ([x, ...xs]) => x
const tail = ([_, ...xs]) => xs
const last = array => head(array.slice(-1))
const init = array => array.slice(0, -1)
const __ = {
toString: _ => 'Curry Placeholder'
}
Object.freeze(__)
const curry = func => {
const replacePlaceholder = (old, args, acc = []) => {
if (old.length == 0) {
return [...acc, ...args]
} else {
const [x, ...xs] = old
if (x === __) {
const [y, ...ys] = args
return replacePlaceholder(xs, ys, [...acc, y])
} else {
return replacePlaceholder(xs, args, [...acc, x])
}
}
}
const continueCurry = (old, ...args) => {
const now = replacePlaceholder(old, args)
const { length } = now.filter(x => x !== __)
if (func.length <= length) {
return func.apply(null, now)
} else {
return continueCurry.bind(null, now)
}
}
return continueCurry.bind(null, [])
}
const zip = curry((array1, array2) => {
if (array1.length == 0 || array2.length == 0) {
return []
} else {
const [x, ...xs] = array1
const [y, ...ys] = array2
return [[x, y], ...zip(xs, ys)]
}
})
const quickSort = array => {
if (array.length < 2) {
return array
} else {
const [x, ...xs] = array
const left = xs.filter(el => el < x)
const right = xs.filter(el => el >= x)
return [...quickSort(left), x, ...quickSort(right)]
}
}
const range = length => Array.from({ length }, (_, i) => i)
const repeat = length => x => Array.from({ length }, _ => x)
const map = curry((func, array) => {
if (array.length == 0) {
return []
} else {
const [x, ...xs] = array
return [func(x), ...map(func, xs)]
}
})
const filter = curry((func, array) => {
if (array.length == 0) {
return []
} else {
const [x, ...xs] = array
const filtered = func(x) ? [x] : []
return [...filtered, ...filter(func, xs)]
}
})
const reduce = curry((func, acc, array) => {
if (array.length == 0) {
return acc
} else {
const [x, ...xs] = array
return reduce(func, func(acc, x), xs)
}
})
const flip = func => curry((y, x, ...args) => func(x, y, ...args))
const max = reduce((acc, el) => (acc > el ? acc : el), -Infinity)
const min = reduce((acc, el) => (acc < el ? acc : el), Infinity)
const reverse = reduce((acc, el) => [el, ...acc], [])
const compose = (...funcs) =>
(...args) => {
const initFuncs = funcs.slice(0, -1)
const [lastFunc] = funcs.slice(-1)
return initFuncs.reduceRight(
(acc, func) => func(acc),
lastFunc.apply(null, args)
)
}
const pipe = (...funcs) =>
(...args) => {
const [hFunc, ...tFuncs] = funcs
return tFuncs.reduce((
acc, func) => func(acc),
hFunc.apply(null, args)
)
}
const composeP = (...funcs) =>
x =>
funcs.reduceRight(
(acc, func) => acc.then(func),
Promise.resolve(x)
)
class Just {
constructor(a) {
this._value = a
}
map(f) {
return new Just(f(this._value))
}
maybe(n, f) {
return f(this._value)
}
toString() {
return `Just ${this._value}`
}
}
class Nothing {
constructor() {}
map(f) {
return new Nothing()
}
maybe(n, f) {
return n
}
toSting() {
return 'Nothing'
}
}
const Maybe = {
Nothing: _ => new Nothing(),
Just: a => new Just(a),
of: a => new Just(a),
fromNullable: a => {
if (a === null || a === undefined) {
return new Nothing()
} else {
return new Just(a)
}
}
}
const safeHead = compose(Maybe.fromNullable, head)
class Left {
constructor(a) {
this._value = a
}
map(f) {
return new Left(this._value)
}
bimap(f, _) {
return new Left(f(this._value))
}
either(f, _) {
return f(this._value)
}
toString(){
return `Left ${this._value}`
}
}
class Right {
constructor(b) {
this._value = b
}
map(f) {
return new Right(f(this._value))
}
bimap(_, g) {
return new Right(g(this._value))
}
either(_, g) {
return g(this._value)
}
toString(){
return `Right ${this._value}`
}
}
const Either = {
Left: a => new Left(a),
Right: b => new Right(b),
of: b => new Right(b)
}
const tryCatch = f =>
(...args) => {
try {
return Either.Right(f.apply(null, args))
} catch (e) {
return Either.Left(e)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment