-
Notifications
You must be signed in to change notification settings - Fork 36
Approximating Ramda functions with Partial Lenses
Below is a non-exhaustive list of functions in the style of Ramda implemented using only Partial Lenses.
IMPORTANT: The below implementations are not necessarily perfect matches with similarly named Ramda functions. The below implementations are also not necessarily the best implementations of those functions in terms of Partial Lenses.
The intention is to give the reader one way to gain some insight into the expressiveness of the Partial Lenses library.
It should also be noted that this is not how Partial Lenses are designed to be used. The idea with Partial Lenses is to compose an optic that targets a number of elements in a data structure and then lets you perform various operations on those elements, while also maintaining invariants of said data structure. Most of the below examples encapsulate the used optics, which means that they can no longer be used as optics, which essentially defeats the advantages that optics can provide for manipulating more complex data structures in a compositional manner.
Link to playground with the below code.
const all = (c, xs) => L.all(c, L.elems, xs)
const any = (c, xs) => L.any(c, L.elems, xs)
const append = L.set(L.append)
const assoc = L.set
const assocPath = L.set
const concat = (xs, ys) => L.collect([L.elems, L.elems], [xs, ys])
const contains = (x, xs) => L.or([L.elems, L.is(x)], xs)
const dissoc = L.remove
const dissocPath = L.remove
const drop = (n, xs) => L.modify([L.define([]), L.elems], (x, i) => i < n ? undefined : x, xs)
const dropLast = (n, xs) => L.remove([L.define([]), L.slice(-n, n ? undefined : 0)], xs)
const filter = (xib, xs) => L.modify([L.define([]), L.elems], (x, i) => xib(x, i) ? x : undefined, xs)
const find = (xib, xs) => L.selectAs((x, i) => xib(x, i) ? x : undefined, L.elems, xs)
const findIndex = (xib, xs) => L.selectAs((x, i) => xib(x, i) ? i : undefined, L.elems, xs)
const flatten = L.collect(L.lazy(rec => L.choose(x => Array.isArray(x) ? [L.elems, rec] : [])))
const head = L.get(0)
const indexOf = (x, xs) => findIndex(L.get(L.is(x)), xs)
const init = L.remove([L.define([]), L.last])
const insert = (i, x, xs) => L.set(L.slice(i,i), [x], xs)
const insertAll = (i, ys, xs) => L.set([L.define([]), L.slice(i, i)], ys, xs)
const intersperse = (s, xs) => L.collect([L.elems, (x, i) => i ? [s, x] : [x], L.elems], xs)
const join = (s, ss) => L.join(s, L.elems, ss)
const last = L.get(L.last)
const lens = L.lens
const lensIndex = i => i
const lensPath = p => p
const lensProp = p => p
const map = L.modify(L.elems)
const mean = ns => sum(ns) / ns.length
const none = (c, xs) => L.none(c, L.elems, xs)
const not = L.get(L.complement)
const nth = L.get
const omit = (ks, o) => L.remove([L.define({}), L.props(...ks)], o)
const over = L.modify
const path = L.get
const pathEq = (p, x, o) => L.get([p, L.is(x)], o)
const pathOr = (d, p, x) => L.get([p, L.valueOr(d)], x)
const pathSatisfies = (c, p, x) => L.get([p, c], x)
const pick = (ps, o) => L.get(L.props(...ps), o)
const pipe = (...fs) => L.get(L.compose(...fs)) // Pipe unary functions.
const pluck = (p, xs) => L.modify(L.elems, L.get(p), xs)
const prepend = (x, xs) => L.set(L.slice(0, 0), [x], xs)
const product = L.product(L.elems)
const prop = path // `prop*` === `path*`. Could also have `nth*`.
const propEq = pathEq
const propOr = pathOr
const propSatisfies = pathSatisfies
const props = (ps, o) => L.collect([L.props(...ps), L.values], o)
const reduce = (sxis, s, xs) => L.foldl(sxis, s, L.elems, xs)
const reduceRight = (xsis, s, xs) => L.foldr((s, x, i) => xsis(x, s, i), s, L.elems, xs)
const reject = (xib, xs) => L.modify([L.define([]), L.elems], (x, i) => xib(x, i) ? undefined : x, xs)
const remove = (i, n, xs) => L.remove([L.define([]), L.slice(i, i+n)], xs)
const replace = (re, w, s) => L.set([L.define(""), L.matches(re)], w, s)
const set = L.set
const slice = (si, ei, xs) => L.get(L.slice(si, ei), xs)
const splitAt = (n, xs) => [take(n, xs), drop(n, xs)]
const sum = L.sum(L.elems)
const tail = L.remove([L.define([]), 0])
const take = (n, xs) => L.modify([L.define([]), L.elems], (x, i) => i < n ? x : undefined, xs)
const takeLast = (n, xs) => L.get(L.slice(-n, n ? undefined : -n), xs)
const trim = L.remove([L.define(""), L.matches(/^\s+|\s+$/g)])
const update = L.set
const values = L.collect(L.values)
const view = L.get