4.1.1 • Published 4 years ago

@typed/lenses v4.1.1

Weekly downloads
69
License
Parity-6.0.0
Repository
-
Last release
4 years ago

@typed/lenses -- 2.3.0

Well-typed functional lenses

Get it

yarn add @typed/lenses
# or
npm install --save @typed/lenses

API Documentation

All functions are curried!

Lens

A common interface for Updating objects

export interface Lens<A, B> {
  readonly view: (object: A) => Maybe<B>
  readonly updateAt: LensUpdateAt<A, B>
}

export type LensUpdateAt<A, B> = {
  (f: (previousValue: Maybe<B>) => Maybe<B>, object: A): A
  (f: (previousValue: Maybe<B>) => Maybe<B>): (object: A) => A
}

composeLenses(...lens: Array\<Lens\<any, any>): Lens\<any, any>

Right-to-left lens composition.

export const composeLenses: ComposeLenses = function(
  ...lenses: Array<Lens<any, any>>
): Lens<any, any> {
  return pipeLenses.apply(this, lenses.reverse())
}

lens\<A, B>(getter: (a: A) => B | void, setter: (value: B, a: A) => A): Lens\<A, B>

Given a getter and a setter function, it returns a Lens.

export const lens: LensFn = curry2(__lens)

function __lens<A, B>(getter: (a: A) => B | void, setter: (value: B, a: A) => A): Lens<A, B> {
  function updateAt(f: (value: Maybe<B>) => Maybe<B>, a: A): A {
    const value = f(view(a))

    if (isNothing(value)) return a

    return setter(fromJust(value), a)
  }

  function view(a: A): Maybe<B> {
    return Maybe.of(getter(a))
  }

  return { view, updateAt: curry2(updateAt) }
}

export type LensFn = {
  <A, B>(getter: (a: A) => B, setter: (value: B, a: A) => A): Lens<A, B>
  <A, B>(getter: (a: A) => B): (setter: (value: B, a: A) => A) => Lens<A, B>
}

pipeLenses\<A, B>(...lenses: Array\<Lens\<any, any>>): Lens\<A, B>

Left-to-right composition of Lenses.

export const pipeLenses: PipeLenses = function pipeLenses<A, B>(
  ...lenses: Array<Lens<any, any>>
): Lens<A, B> {
  return lenses.slice(1).reduce(__pipeLenses, lenses[0])
}

function __pipeLenses<A, B, C>(lensAB: Lens<A, B>, lensBC: Lens<B, C>): Lens<A, C> {
  function view(obj: A): Maybe<C> {
    return chain(b => lensBC.view(b), lensAB.view(obj))
  }

  function updateAt(f: (value: Maybe<C>) => Maybe<C>, obj: A): A {
    const value = f(view(obj))

    const nestedObject = lensAB.view(obj)

    if (isNothing(nestedObject)) return obj

    return lensAB.updateAt(
      () => Maybe.of(lensBC.updateAt(() => value, fromJust(nestedObject))),
      obj
    )
  }

  return { view, updateAt: curry2(updateAt) }
}

updateAt\<A, B>(lens: \<A, B>, f: (value: Maybe\<B>) => Maybe\<B>, obj: A): A

Uses a lenses to update a value contained in an object.

export const updateAt: UpdateAt = curry3(function<A, B>(
  lens: Lens<A, B>,
  f: (value: Maybe<B>) => Maybe<B>,
  obj: A
): A {
  return lens.updateAt(f, obj)
})

export type UpdateAt = {
  <A, B>(lens: Lens<A, B>, f: (value: Maybe<B>) => Maybe<B>, obj: A): A
  <A, B>(lens: Lens<A, B>, f: (value: Maybe<B>) => Maybe<B>): (obj: A) => A
  <A, B>(lens: Lens<A, B>): (f: (value: Maybe<B>) => Maybe<B>) => (obj: A) => A
  <A, B>(lens: Lens<A, B>): (f: (value: Maybe<B>) => Maybe<B>, obj: A) => A
}

view\<A, B>(lens: Lens\<A, B>, obj: A): Maybe\<B>

Uses a lenses to view a value contained in an object.

export const view: View = curry2(function<A, B>(lens: Lens<A, B>, obj: A): Maybe<B> {
  return lens.view(obj)
})

export type View = {
  <A, B>(lens: Lens<A, B>, obj: A): Maybe<B>
  <A, B>(lens: Lens<A, B>): (obj: A) => Maybe<B>
}
4.1.1

4 years ago

4.1.0

4 years ago

4.0.0

4 years ago

3.0.0

5 years ago

2.3.0

6 years ago

2.2.0

7 years ago

2.1.0

7 years ago

2.0.0

7 years ago

1.1.0

7 years ago

1.0.0

7 years ago