import { Maybe , chain , fromJust , isNothing } from '@typed/maybe' ; import { Lens } from '../types' ; import { PipeLenses } from './types' ; import { curry2 } from '@typed/functions' ; name export const pipeLenses = function pipeLenses < A , B > ( ... lenses ) : Lens < A , B > { return lenses . slice ( 1 ) . reduce ( __pipeLenses , lenses [ 0 ] ) ; } ; function __pipeLenses < A , B , C > ( lensAB , lensBC ) { function view ( obj ) { return chain ( b => lensBC . view ( b ) , lensAB . view ( obj ) ) ; } function updateAt ( f , obj ) { 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 ) } ; }