since import { Applicative as ApplicativeHKT , Applicative1 } from 'fp-ts/lib/Applicative' ; import { Apply1 } from 'fp-ts/lib/Apply' ; import * as A from 'fp-ts/lib/Array' ; import { Comonad1 } from 'fp-ts/lib/Comonad' ; import { Extend1 } from 'fp-ts/lib/Extend' ; import { Foldable1 } from 'fp-ts/lib/Foldable' ; import { decrement , increment , identity , Predicate } from 'fp-ts/lib/function' ; import { Functor1 } from 'fp-ts/lib/Functor' ; import { FunctorWithIndex1 } from 'fp-ts/lib/FunctorWithIndex' ; import { HKT } from 'fp-ts/lib/HKT' ; import { Monoid } from 'fp-ts/lib/Monoid' ; import * as NEA from 'fp-ts/lib/NonEmptyArray' ; import * as O from 'fp-ts/lib/Option' ; import { pipe } from 'fp-ts/lib/pipeable' ; import * as RA from 'fp-ts/lib/ReadonlyArray' ; import { Semigroup } from 'fp-ts/lib/Semigroup' ; import { Show } from 'fp-ts/lib/Show' ; import { Traversable1 } from 'fp-ts/lib/Traversable' ; import { ReadonlyNonEmptyArray } from 'fp-ts/ReadonlyNonEmptyArray' ; import NonEmptyArray = NEA . NonEmptyArray ; import Option = O . Option ; category since export interface Zipper < A > { readonly lefts : Array < A > ; readonly focus : A ; readonly rights : Array < A > ; } category since export const make = ( lefts , focus , rights ) => ( { lefts : lefts . slice ( ) , focus , rights : rights . slice ( ) } ) ; category since export const fromReadonlyArray = ( as , focusIndex = 0 ) => { if ( RA . isEmpty ( as ) || RA . isOutOfBound ( focusIndex , as ) ) { return O . none ; } else { return O . some ( make ( pipe ( as . slice ( ) , A . takeLeft ( focusIndex ) ) , as [ focusIndex ] , pipe ( as . slice ( ) , A . dropLeft ( focusIndex + 1 ) ) ) ) ; } } ; category since export const fromArray = fromReadonlyArray ; category since export const fromReadonlyNonEmptyArray = ( nea ) => make ( [ ] , nea [ 0 ] , nea . slice ( 1 ) ) ; category since export const fromNonEmptyArray = fromReadonlyNonEmptyArray ; category since export const isOutOfBound = ( index , fa ) => index < 0 || index >= length ( fa ) ; category since export const length = ( fa ) => fa . lefts . length + 1 + fa . rights . length ; category since export const toNonEmptyArray = ( fa ) => pipe ( NEA . of ( fa . focus ) , ( as ) => NEA . concat ( fa . lefts , as ) , ( as ) => NEA . concat ( as , fa . rights ) ) ; category since export const toReadonlyNonEmptyArray = toNonEmptyArray ; category since deprecated Use the new  toNonEmptyArray destructor instead.
  export const toArray = toNonEmptyArray ; category since export const update = ( a ) => ( fa ) => make ( fa . lefts , a , fa . rights ) ; category since export const modify = ( f ) => ( fa ) => pipe ( fa , update ( f ( fa . focus ) ) ) ; category since export const move = ( f , fa ) => { const newIndex = f ( fa . lefts . length ) ; if ( isOutOfBound ( newIndex , fa ) ) { return O . none ; } else { return fromArray ( toNonEmptyArray ( fa ) , newIndex ) ; } } ; category since export const findIndex = < A > ( predicate ) => ( fa ) : Option < number > => pipe ( fa . lefts , RA . findIndex ( predicate ) , O . alt ( ( ) => ( predicate ( fa . focus ) ? O . some ( fa . lefts . length ) : O . none ) ) , O . alt ( ( ) => pipe ( fa . rights , RA . findIndex ( predicate ) , O . map ( ( i ) => fa . lefts . length + 1 + i ) ) ) ) ; category since export const moveByFindFirst = < A > ( predicate ) => ( fa ) : Option < Zipper < A > > => pipe ( fa , findIndex ( predicate ) , O . chain ( ( i ) => ( i === fa . lefts . length ? O . some ( fa ) : move ( ( ) => i , fa ) ) ) ) ; category since export const up = ( fa ) => move ( decrement , fa ) ; category since export const down = ( fa ) => move ( increment , fa ) ; category since export const start = ( fa ) => { if ( A . isEmpty ( fa . lefts ) ) { return fa ; } else { return make ( [ ] , fa . lefts [ 0 ] , A . snoc ( pipe ( fa . lefts , A . dropLeft ( 1 ) ) , fa . focus ) . concat ( fa . rights ) ) ; } } ; category since export const end = ( fa ) => { const len = fa . rights . length ; if ( len === 0 ) { return fa ; } else { return make ( A . snoc ( fa . lefts , fa . focus ) . concat ( pipe ( fa . rights , A . takeLeft ( len - 1 ) ) ) , fa . rights [ len - 1 ] , [ ] ) ; } } ; category since export const insertLeft = ( a ) => ( fa ) => make ( fa . lefts , a , A . cons ( fa . focus , fa . rights ) ) ; category since export const insertRight = ( a ) => ( fa ) => make ( A . snoc ( fa . lefts , fa . focus ) , a , fa . rights ) ; category since export const deleteLeft = ( fa ) => { const len = fa . lefts . length ; return fromArray ( fa . lefts . concat ( fa . rights ) , len > 0 ? len - 1 : 0 ) ; } ; category since export const deleteRight = ( fa ) => { const lenl = fa . lefts . length ; const lenr = fa . rights . length ; return fromArray ( fa . lefts . concat ( fa . rights ) , lenr > 0 ? lenl : lenl - 1 ) ; } ; const map_ = ( fa , f ) => make ( fa . lefts . map ( f ) , f ( fa . focus ) , fa . rights . map ( f ) ) ; const mapWithIndex_ = ( fa , f ) => { const l = fa . lefts . length ; return make ( fa . lefts . map ( ( a , i ) => f ( i , a ) ) , f ( l , fa . focus ) , fa . rights . map ( ( a , i ) => f ( l + 1 + i , a ) ) ) ; } ; const ap_ = ( fab , fa ) => make ( A . array . ap ( fab . lefts , fa . lefts ) , fab . focus ( fa . focus ) , A . array . ap ( fab . rights , fa . rights ) ) ; const extend_ = ( fa , f ) => { const lefts = fa . lefts . map ( ( a , i ) => f ( make ( pipe ( fa . lefts , A . takeLeft ( i ) ) , a , A . snoc ( pipe ( fa . lefts , A . dropLeft ( i + 1 ) ) , fa . focus ) . concat ( fa . rights ) ) ) ) ; const rights = fa . rights . map ( ( a , i ) => f ( make ( A . snoc ( fa . lefts , fa . focus ) . concat ( pipe ( fa . rights , A . takeLeft ( i ) ) ) , a , pipe ( fa . rights , A . dropLeft ( i + 1 ) ) ) ) ) ; return make ( lefts , f ( fa ) , rights ) ; } ; const reduce_ = ( fa , b , f ) => fa . rights . reduce ( f , f ( fa . lefts . reduce ( f , b ) , fa . focus ) ) ; const reduceRight_ = ( fa , b , f ) => { const rights = fa . rights . reduceRight ( ( acc , a ) => f ( a , acc ) , b ) ; const focus = f ( fa . focus , rights ) ; return fa . lefts . reduceRight ( ( acc , a ) => f ( a , acc ) , focus ) ; } ; const foldMap_ = ( M ) => ( fa , f ) => { const lefts = fa . lefts . reduce ( ( acc , a ) => M . concat ( acc , f ( a ) ) , M . empty ) ; const rights = fa . rights . reduce ( ( acc , a ) => M . concat ( acc , f ( a ) ) , M . empty ) ; return M . concat ( M . concat ( lefts , f ( fa . focus ) ) , rights ) ; } ; const traverse_ = < F > ( F ) : ( < A , B > ( ta : Zipper < A > , f : ( a : A ) => HKT < F , B > ) => HKT < F , Zipper < B > > ) => { const traverseF = A . array . traverse ( F ) ; return < A , B > ( ta , f ) => F . ap ( F . ap ( F . map ( traverseF ( ta . lefts , f ) , ( lefts ) => ( focus ) => ( rights ) => make ( lefts , focus , rights ) ) , f ( ta . focus ) ) , traverseF ( ta . rights , f ) ) ; } ; category since export const map = ( f ) => ( fa ) => map_ ( fa , f ) ; category since export const mapWithIndex = ( f ) => ( fa ) => mapWithIndex_ ( fa , f ) ; category since export const ap = ( fa ) => ( fab ) => ap_ ( fab , fa ) ; category since export const apFirst = < B > ( fb ) => < A > ( fa ) : Zipper < A > => pipe ( fa , map ( ( a ) => ( _ ) => a ) , ap ( fb ) ) ; category since export const apSecond = < B > ( fb ) => < A > ( fa ) : Zipper < B > => pipe ( fa , map ( ( ) => ( b ) => b ) , ap ( fb ) ) ; category since export const of = ( focus ) => make ( [ ] , focus , [ ] ) ; category since export const extend = ( f ) => ( wa ) => extend_ ( wa , f ) ; category since export const duplicate = extend ( identity ) ; category since export const foldMap = ( M ) => ( f ) => ( fa ) => foldMap_ ( M ) ( fa , f ) ; category since export const reduce = ( b , f ) => ( fa ) => reduce_ ( fa , b , f ) ; category since export const reduceRight = ( b , f ) => ( fa ) => reduceRight_ ( fa , b , f ) ; category since export const sequence = < F > ( F ) : ( < A > ( ta : Zipper < HKT < F , A > > ) => HKT < F , Zipper < A > > ) => { const sequenceF = A . array . sequence ( F ) ; return < A > ( ta ) => F . ap ( F . ap ( F . map ( sequenceF ( ta . lefts ) , ( lefts ) => ( focus ) => ( rights ) => make ( lefts , focus , rights ) ) , ta . focus ) , sequenceF ( ta . rights ) ) ; } ; category since export const extract = ( fa ) => fa . focus ; category since export const URI = 'Zipper' ; category since export type URI = typeof URI ; declare module 'fp-ts/lib/HKT' { interface URItoKind < A > { Zipper : Zipper < A > ; } } category since export const getShow = ( S ) => { const SA = A . getShow ( S ) ; return { show : ( fa ) => `Zipper(${ SA . show ( fa . lefts ) }, ${ S . show ( fa . focus ) }, ${ SA . show ( fa . rights ) })` } ; } ; category since export const getSemigroup = ( S ) => ( { concat : ( x , y ) => make ( x . lefts . concat ( y . lefts ) , S . concat ( x . focus , y . focus ) , x . rights . concat ( y . rights ) ) } ) ; category since export const getMonoid = ( M ) => ( { ... getSemigroup ( M ) , empty : make ( [ ] , M . empty , [ ] ) } ) ; category since export const Functor = { URI , map : map_ } ; category since export const FunctorWithIndex = { URI , map : map_ , mapWithIndex : mapWithIndex_ } ; category since export const Applicative = { URI , map : map_ , ap : ap_ , of } ; category since export const Apply = { URI , map : map_ , ap : ap_ } ; category since export const Foldable = { URI , foldMap : foldMap_ , reduce : reduce_ , reduceRight : reduceRight_ } ; category since export const Traversable = { URI , map : map_ , foldMap : foldMap_ , reduce : reduce_ , reduceRight : reduceRight_ , traverse : traverse_ , sequence } ; category since export const Comonad = { URI , map : map_ , extend : extend_ , extract } ; category since export const zipper = { URI , map : map_ , of , ap : ap_ , extend : extend_ , extract , reduce : reduce_ , reduceRight : reduceRight_ , foldMap : foldMap_ , traverse : traverse_ , sequence , mapWithIndex : mapWithIndex_ } ;