I'm trying to write a simple Parser, so all the declarations are listed in the image below, but when I try to compile this module it fails. I'm following the tutorial provided by this source -> Haskell lessons suggested by official site and specifically this video by Dr. Erik Meijer (Lesson on Parser with "do" construct).
The problem is that I thought that the "do" construct was able to "concatenate" outputs from a previous function in a descending way, but the way that this p function should work seems to be magic to me. What's the right implementation?
-- Generic Parser.
type Parser a = String -> [(a, String)]
-- A simple Parser that captures the first char of the string, puts it in
-- the first position of the couple and then puts the rest of the string into
-- the second place of the couple inside the singleton list.
item :: Parser Char
item = \inp -> case inp of
[] -> []
(x:xs) -> [(x, xs)]
-- Simple parser that always fails.
failure :: Parser a
failure = \inp -> []
-- Returns the type of the parser without operating on the input.
return1 :: a -> Parser a
return1 v = \inp -> [(v, inp)]
-- Explicit call to parse.
parse :: Parser a -> String -> [(a, String)]
parse p inp = p inp
-- Some kind of "or" operator that if the first parser fails (returning an empty list) it
-- parses the second parser.
(+++) :: Parser a -> Parser a -> Parser a
p +++ q = \inp -> case p inp of
[] -> parse q inp
[(v, out)] -> [(v, out)]
-- The function within I'm having troubles.
p :: Parser (Char,Char)
p = do
x <- item
item
y <- item
return1 (x, y)



Monadinstance forParser?pis making use of the(->) Stringmonad, not any kind ofParsermonad. You need to makeParseranewtype, and then write theMonadinstance for it before you can usedoas you want.Parseran instance ofMonadin a way that makes monadic parsing work. The problem is,String ->is an instance ofMonad(so the do notation works), but it's a wrong instance and produces all the wrong types.Try to rewrite this function using an explicitbindrather thando. Alternatively you can wrapParserin a newtype like thisnewtype Parser a = Parser { unparser :: String -> [(a, String)] }and define a Monad instance for that... but that's probably too much for the first Monad lesson...