// @flow import type { Either } from './Either' import type { Functor } from './Functor' import { HKT } from './HKT' import * as either from './Either' /* A [[PSetter]] is a generalisation of Functor map: - `map: (A => B) => F[A] => F[B]` - `modify: (A => B) => S => T` */ export interface PSetter { modify(f: (a: A) => B, s: S): T } export type Setter = PSetter; export function set(setter: PSetter, b: B, s: S): T { return setter.modify(() => b, s) } /** join two PSetter with the same target */ export function choice(setter1: PSetter, setter2: PSetter): PSetter, Either, A, B> { return { modify(f: (a: A) => B, s: Either): Either { return either.either( s1 => either.left(setter1.modify(f, s1)), s2 => either.right(setter2.modify(f, s2)), s ) } } } export function composeSetter(abcd: PSetter, stab: PSetter): PSetter { return { modify(f: (c: C) => D, s: S): T { return stab.modify(c => abcd.modify(f, c), s) } } } export function fromFunctor(functor: Functor): PSetter, HKT, A, B> { return { modify(f: (a: A) => B, s: HKT): HKT { return functor.map(f, s) } } }