The code is as below:
type Parser a = String -> [(a, String)]
retrn :: a -> Parser a
retrn v = \inp -> [(v, inp)]
parse :: Parser a -> String -> [(a, String)]
parse p inp = p inp
item :: Parser Char
item = \inp -> case inp of
[] -> []
(x:xs) -> [(x, xs)]
--problem code
p :: Parser (Char, Char)
p = do x <- item
item
y <- item
retrn (x, y)
It gives the following type error:
SO-34035520.hs:19:8:
Couldn't match type `[(Char, String)]' with `Char'
Expected type: String -> [((Char, Char), String)]
Actual type: Parser ([(Char, String)], [(Char, String)])
In a stmt of a 'do' block: retrn (x, y)
In the expression:
do { x <- item;
item;
y <- item;
retrn (x, y) }
What noteworthy is, the sample code that is on official website of the book can be interpreted smoothly, which is *.lhs format.
So, can somebody tell me why? I've been working on this struggle for days.
Thanks in advance.
(->) String has a Monad instance but it is not what you are looking for. When you use do-notation in the definition of p, this instance is the one that is picked up.
What you want to do is make your own Monad instance for Parser (this requires changing it from a type synonym to a newtype wrapper over String -> [(a, String)]) and then let that be picked up in the definition of p.
Note that your example code already has an implementation of return (under the name of retrn) which does the right thing, and it is also very different from what return for (->) String is (which would be retrn v = \inp -> v.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With