since import { Alt2 } from 'fp-ts/lib/Alt' ; import { Alternative2 } from 'fp-ts/lib/Alternative' ; import { Applicative2 } from 'fp-ts/lib/Applicative' ; import * as A from 'fp-ts/lib/Array' ; import { Chain2 } from 'fp-ts/lib/Chain' ; import { tailRec , ChainRec2 } from 'fp-ts/ChainRec' ; import * as E from 'fp-ts/lib/Either' ; import { Functor2 } from 'fp-ts/lib/Functor' ; import { Monad2 } from 'fp-ts/lib/Monad' ; import { Monoid } from 'fp-ts/lib/Monoid' ; import * as NEA from 'fp-ts/lib/NonEmptyArray' ; import * as O from 'fp-ts/lib/Option' ; import * as RA from 'fp-ts/lib/ReadonlyArray' ; import * as RNEA from 'fp-ts/lib/ReadonlyNonEmptyArray' ; import { Semigroup } from 'fp-ts/lib/Semigroup' ; import { identity , not , Lazy , Predicate , Refinement } from 'fp-ts/lib/function' ; import { pipe } from 'fp-ts/lib/pipeable' ; import { error , escalate , extend , success , withExpected , ParseResult , ParseSuccess } from './ParseResult' ; import { atEnd , getAndNext , Stream } from './Stream' ; category since export interface Parser < I , A > { ( i ) : ParseResult < I , A > ; } category since export const succeed = a => i => success ( a , i , i ) ; category since export const fail = ( ) => i => error ( i ) ; category since export const failAt = i => ( ) => error ( i ) ; category since export const sat = < I > ( predicate ) : Parser < I , I > => pipe ( withStart ( item < I > ( ) ) , chain ( ( [ a , start ] ) => ( predicate ( a ) ? of ( a ) : failAt ( start ) ) ) ) ; category since export const expected = ( p , message ) => i => pipe ( p ( i ) , E . mapLeft ( err => withExpected ( err , [ message ] ) ) ) ; category since export const item = ( ) => i => pipe ( getAndNext ( i ) , O . fold ( ( ) => error ( i ) , ( { value , next } ) => success ( value , next , i ) ) ) ; category since export const cut = p => i => pipe ( p ( i ) , E . mapLeft ( escalate ) ) ; category since export const cutWith = ( p1 , p2 ) => pipe ( p1 , apSecond ( cut ( p2 ) ) ) ; category since export const seq = ( fa , f ) => i => pipe ( fa ( i ) , E . chain ( s => pipe ( f ( s . value ) ( s . next ) , E . chain ( next => success ( next . value , next . next , i ) ) ) ) ) ; category since export const either = ( p , f ) => i => { const e = p ( i ) ; if ( E . isRight ( e ) ) { return e ; } if ( e . left . fatal ) { return e ; } return pipe ( f ( ) ( i ) , E . mapLeft ( err => extend ( e . left , err ) ) ) ; } ; category since export const withStart = p => i => pipe ( p ( i ) , E . map ( s => ( { ... s , value : [ s . value , i ] } ) ) ) ; category since export const maybe = M => alt ( ( ) => of ( M . empty ) ) ; category since export const eof = ( ) => expected ( i => ( atEnd ( i ) ? success ( undefined , i , i ) : error ( i ) ) , 'end of file' ) ; category since export const many = < I , A > ( p ) : Parser < I , Array < A > > => pipe ( many1 ( p ) , alt ( ( ) => of < I , Array < A > > ( A . empty ) ) ) ; category since export const many1 = < I , A > ( parser ) : Parser < I , NEA . NonEmptyArray < A > > => pipe ( parser , chain ( head => chainRec_ ( NEA . of ( head ) , acc => pipe ( parser , map ( a => E . left ( NEA . snoc ( acc , a ) ) ) , alt ( ( ) => of ( E . right ( acc ) ) ) ) ) ) ) ; category since export const sepBy = < I , A , B > ( sep , p ) : Parser < I , Array < B > > => { const nil = of ( A . empty ) ; return pipe ( sepBy1 ( sep , p ) , alt ( ( ) => nil ) ) ; } ; category since export const sepBy1 = ( sep , p ) => pipe ( p , chain ( head => pipe ( many ( pipe ( sep , apSecond ( p ) ) ) , map ( tail => NEA . cons ( head , tail ) ) ) ) ) ; category since export const sepByCut = ( sep , p ) => pipe ( p , chain ( head => pipe ( many ( cutWith ( sep , p ) ) , map ( tail => NEA . cons ( head , tail ) ) ) ) ) ; example category since export const filter = < A > ( predicate ) => < I > ( p ) : Parser < I , A > => i => pipe ( p ( i ) , E . chain ( next => ( predicate ( next . value ) ? E . right ( next ) : error ( i ) ) ) ) ; category since export const between = ( left , right ) => p => pipe ( left , chain ( ( ) => p ) , chainFirst ( ( ) => right ) ) ; category since export const surroundedBy = bound => between ( bound , bound ) ; example category since export const lookAhead = p => i => pipe ( p ( i ) , E . chain ( next => success ( next . value , i , i ) ) ) ; example category since export const takeUntil = predicate => many ( sat ( not ( predicate ) ) ) ; example category since export const optional = < I , A > ( parser ) : Parser < I , O . Option < A > > => pipe ( parser , map ( O . some ) , alt ( ( ) => succeed < I , O . Option < A > > ( O . none ) ) ) ; example category since export const manyTill = < I , A , B > ( parser , terminator ) : Parser < I , ReadonlyArray < A > > => pipe ( terminator , map < B , ReadonlyArray < A > > ( ( ) => RA . empty ) , alt < I , ReadonlyArray < A > > ( ( ) => many1Till ( parser , terminator ) ) ) ; example category since export const many1Till = < I , A , B > ( parser , terminator ) : Parser < I , RNEA . ReadonlyNonEmptyArray < A > > => pipe ( parser , chain ( x => chainRec_ ( RNEA . of ( x ) , acc => pipe ( terminator , map ( ( ) => E . right ( acc ) ) , alt ( ( ) => pipe ( parser , map ( a => E . left ( RNEA . snoc ( acc , a ) ) ) ) ) ) ) ) ) ; interface Next < I , A > { readonly value : A ; readonly stream : Stream < I > ; } const map_ = ( ma , f ) => i => pipe ( ma ( i ) , E . map ( s => ( { ... s , value : f ( s . value ) } ) ) ) ; const ap_ = ( mab , ma ) => chain_ ( mab , f => map_ ( ma , f ) ) ; const chain_ = ( ma , f ) => seq ( ma , f ) ; const chainRec_ = < I , A , B > ( a , f ) : Parser < I , B > => { const split = ( start ) => ( result ) : E . Either < Next < I , A > , ParseResult < I , B > > => E . isLeft ( result . value ) ? E . left ( { value : result . value . left , stream : result . next } ) : E . right ( success ( result . value . right , result . next , start ) ) ; return start => tailRec ( { value : a , stream : start } , state => { const result = f ( state . value ) ( state . stream ) ; if ( E . isLeft ( result ) ) { return E . right ( error ( state . stream , result . left . expected , result . left . fatal ) ) ; } return split ( start ) ( result . right ) ; } ) ; } ; const alt_ = ( fa , that ) => either ( fa , that ) ; category since export const map = f => fa => map_ ( fa , f ) ; category since export const ap = fa => fab => ap_ ( fab , fa ) ; category since export const apFirst = fb => fa => ap_ ( map_ ( fa , a => ( ) => a ) , fb ) ; category since export const apSecond = fb => fa => ap_ ( map_ ( fa , ( ) => b => b ) , fb ) ; category since export const of = succeed ; category since export const chain = f => ma => chain_ ( ma , f ) ; category since export const chainFirst = f => ma => chain_ ( ma , a => map_ ( f ( a ) , ( ) => a ) ) ; category since export const alt = that => fa => alt_ ( fa , that ) ; category since export const flatten = mma => chain_ ( mma , identity ) ; category since export const zero = fail ; category since export const URI = 'Parser' ; category since export type URI = typeof URI ; declare module 'fp-ts/lib/HKT' { interface URItoKind2 < E , A > { Parser : Parser < E , A > ; } } category since export const getSemigroup = S => ( { concat : ( x , y ) => ap_ ( map_ ( x , x => y => S . concat ( x , y ) ) , y ) } ) ; category since export const getMonoid = M => ( { ... getSemigroup ( M ) , empty : succeed ( M . empty ) } ) ; category since export const Functor = { URI , map : map_ } ; category since export const Applicative = { URI , map : map_ , ap : ap_ , of } ; category since export const Monad = { URI , map : map_ , ap : ap_ , of , chain : chain_ } ; category since export const ChainRec = { URI , map : map_ , ap : ap_ , chain : chain_ , chainRec : chainRec_ } ; category since export const Alt = { URI , map : map_ , alt : alt_ } ; category since export const Alternative = { URI , map : map_ , of , ap : ap_ , alt : alt_ , zero : fail } ; category since export const parser = { URI , map : map_ , of , ap : ap_ , chain : chain_ , alt : alt_ , zero : fail } ; internal const bind_ = < A , N extends string , B > ( a , name , b ) : { [ K in keyof A | N ] : K extends keyof A ? A [ K ] : B ; } => Object . assign ( { } , a , { [ name ] : b } ) as any ; since export const bindTo = < N extends string > ( name ) => < I , A > ( fa ) : Parser < I , { [ K in N ] : A ; } > => pipe ( fa , map ( a => bind_ ( { } , name , a ) ) ) ; since export const bind = < N extends string , I , A , B > ( name , f ) => ( fa ) : Parser < I , { [ K in keyof A | N ] : K extends keyof A ? A [ K ] : B ; } > => pipe ( fa , chain ( a => pipe ( f ( a ) , map ( b => bind_ ( a , name , b ) ) ) ) ) ;