Created
May 13, 2022 06:11
-
-
Save jrsinclair/e4d9d73e9c7e5947de2612497f9cfb16 to your computer and use it in GitHub Desktop.
Lenses that seem to work in Flow
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// @flow strict-local | |
// Lenses | |
// ------------------------------------------------------------------------------------------------ | |
export type LensInternal<S, T, A, B> = { | |
getVal: (S) => A, | |
setVal: (B, S) => T, | |
}; | |
export type Lens<S, T, A, B> = { | |
(): LensInternal<S, T, A, B>, | |
compose: <C, D>(Lens<A, B, C, D>) => Lens<S, T, C, D>, | |
}; | |
export const lens = <S, T, A, B>(getVal: (S) => A, setVal: (B, S) => T): Lens<S, T, A, B> => { | |
const lensFunc = () => ({ getVal, setVal }); | |
lensFunc.compose = <C, D>(l: Lens<A, B, C, D>): Lens<S, T, C, D> => { | |
const { getVal: g2, setVal: s2 } = l(); | |
return lens( | |
(x: S) => g2(getVal(x)), | |
(val: D, obj: S): T => setVal(s2(val, getVal(obj)), obj), | |
); | |
}; | |
return lensFunc; | |
}; | |
export const view = <S, T, A, B>(l: Lens<S, T, A, B>, obj: S): A => l().getVal(obj); | |
export const set = <S, T, A, B>(l: Lens<S, T, A, B>, val: B, obj: S): T => l().setVal(val, obj); | |
export const lensCompose = <S, T, A, B, C, D>( | |
l1: Lens<S, T, A, B>, | |
l2: Lens<A, B, C, D>, | |
): Lens<S, T, C, D> => l1.compose(l2); | |
type L<A, B> = Lens<A, A, B, B>; | |
export const propLens = <S, K: string, A, B>( | |
k: K, | |
): Lens<{ ...S, +[K]: A }, { ...S, +[K]: B }, A, B> => | |
lens( | |
(s) => s[k], | |
(val, obj: S) => ({ ...obj, [k]: val }), | |
); | |
export const idxLens = <T>(idx: number): L<$ReadOnlyArray<T>, T> => | |
lens( | |
(arr) => arr[idx], | |
(val, arr) => arr.slice(0, idx).concat([val]).concat(arr.slice(idx)), | |
); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment