calmm-js / partial.lenses

Partial lenses is a comprehensive, high-performance optics library for JavaScript

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Additions to consider

polytypic opened this issue · comments

Under consideration

  • Async versions of folds, see #210.

  • Add convenient specializations of L.forEachWith to e.g. collect pairs as an object or a Map or values as a Set. Consider draft L.collectObjectFromPairs, but likely the API for this might be more like e.g. into from Ramda like in this draft L.into.

  • Additional traversal "modifiers" e.g. draft uniq and scan modifiers.

  • Adding side-effects:

    L.tapR: (s -> Undefined) -> POptic s s = ef => L.getter(v => (ef(v), v))
    L.tapW: ((s, s) -> Undefined) -> POptic s s = ef => L.setter((n, o) => (ef(n, o), n))
  • Convenience:

    L.getOr: a -> PLens s a -> s -> a
  • Enhance L.mapping and L.pattern:

    • Add ability to apply isomorphisms in the patterns of L.mapping.
    • Consider adding logical pattern combinators (and, or, not).
    • Treat unary functions in pattern as predicates.
  • Isomorphisms between numbers and strings:

    L.number: PIso String Number
    L.parseInt: radix: Integer -> PIso String Integer
    L.parseFloat: PIso String Number
  • Total variants of traversals (where undefined array elements are not dropped):

    L.childrenTotal
    L.leafsTotal
    L.satisfyingTotal
    L.queryTotal
    // ... others?

Implemented

  • Handy special case of L.satisfying:

    L.whereEq(template) = L.satisfying(L.and(L.branch(L.modify(L.leafs, L.is, template))))
  • For convenience, support implicit compose in L.partsOf:

    L.partsOf(optic, ...optics) = L.partsOf([optic, ...optics])
  • Lenses for special updates:

    L.appendTo: PLens [a] a // Is current `L.append` renamed
    L.prependTo: PLens [a] a
    L.assignTo: PLens {...} {...}
  • Iso combinators on arrays:

    L.zipWith1: PIso (a, b) c -> PIso (a, [b]) -> PIso [c]
    L.zipWith: PIso (a, b) c -> PIso ([a], [b]) -> PIso [c]
  • Iso combinator to restrict to a subset by pattern matching.

    L.pattern((...vs) => pattern) = L.mapping((...vs) => [pattern, pattern])
  • Combinator to ignore props of an object:

    L.propsExcept(...propNames) = [L.disjoint(k => propNames.includes(k) ? 'd' : 't'), 't']
  • Isomorphism combinators:

    L.conjugate: (sa: PIso s a) -> (aa: PIso a a) -> PIso s s = [sa, aa, L.inverse(sa)]
    L.applyAt: (sa: POptic s a) -> (aa: PIso a a) -> PIso s s

Dropped

  • Iso combinator to attempt an iso:

    L.attempt: PIso a a -> PIso a a = aIa => L.alternatives(aIa, [])

    It seems better to push the attempt behaviour into elimination forms like attemptEveryUp so that alternatives remain composable.

  • To convert a traversal addressing a single element to a lens:

    L.selectLens(traversal) = L.foldTraversalLens(L.select, traversal)

    There seem to be better ways.