newtypeParsera=Parser(String->[(a,String)])instanceMonadParserwhere-- (>>=) :: Parser a -> (a -> Parser b) -> Parser bp>>=f=P(\inp->caseparsepinpof[]->[][(v,out)]->parse(fv)out)
combinator many
Coq vs. Haskell
explicit recursion depth, .e. step-indexed
explicit exception optionE (in Haskell, it’s hidden behind the Parser Monad as [])
explicit string state xs (in Haskell, it’s hidden behind the Parser Monad as String -> String)
explicit accepted token (in Haskell, it’s hidden behind the Parser Monad as a, argument)
1
2
3
4
5
6
7
8
9
10
11
12
Fixpointmany_helper{T}(p:parserT)accstepsxs:=matchsteps,pxswith|0,_⇒NoneE"Too many recursive calls"|_,NoneE_⇒SomeE((revacc),xs)|Ssteps',SomeE(t,xs')⇒many_helperp(t::acc)steps'xs'end.Fixpointmany{T}(p:parserT)(steps:nat):parser(listT):=many_helperp[]steps.
1
2
3
4
5
6
7
8
9
manyL::Parsera->Parser[a]manyLp=many1Lp<++return[]-- left biased ORmany1L::Parsera->Parser[a]many1Lp=(:)<$>p<*>manyLp-- ormany1Lp=dox<-pxs<-manyLpreturn(x:xs)