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