Assuming we are going to parse an expression like this:
Exp := MulMul := Add {'*' Add}Add := Literal {'+' Literal}Literal := number | '(' Exp ')'
In Haskell, we can write a parser like
exp = mulmul = do foo <- add bar <- many (char '*'>> add) return -- somethingadd = do foo <- literal bar <- many (char '-'>> literal) return -- somethingliteral = number <|> do _ <- char '(' x <- exp _ <- char ')' return x
But in ocaml, the "same" code like this:
let rec exp = muland mul = (* ... *)and add = (* ... *)and literal = (* ... *)
will cause a compilation error
This kind of expression is not allowed as right-hand side of let rec
I understand that it's because of the eager evaluation in ocaml. And now I have come up with two solutions, neither are as clean as haskell though.
let rec exp input = mul input (* the first one is to write the state as param explicitly *)and (* ... *)let rec exp = lazy (Lazy.force mul) (* the second one is to mark every parser as lazy *)and (* ... *)
Therefore, I wonder if there is a clean way to write (monadic) parser in ocaml?