
I'm trying to learn Haskell using Hutton's book and Hugs (Sep 06), and am trying to work the parsing examples (chapter 8, Functional parsers), but I can't understand the error I'm seeing when I try to load the program into Hugs. Following the book, I've defined a Parser type, then written the basic parsers, then a sequencing operator >>=, followed by the example p parser (bottom of page 77). However, trying to load this file in Hugs generates an error (caused by the definition of p). I've given below the entire file I've created and the error message I get on trying to load it. Any help much appreciated - Arindam ---------------------------------------- type Parser a = String -> [(a, String)] return :: a -> Parser a return v = \inp -> [(v, inp)] failure :: Parser a failure = \inp -> [] item :: Parser Char item = \inp -> case inp of [] -> [] (x:xs) -> [(x, xs)] parse :: Parser a -> String -> [(a, String)] parse p inp = p inp (>>=) :: Parser a -> (a -> Parser b) -> Parser b p >>= f = \inp -> case parse p inp of [] -> [] [(v, out)] -> parse (f v) out p :: Parser (Char, Char) p = do x <- item item y <- item Main.return (x, y) ------------------------------------------ Hugs> :r ERROR file:c:\parsers.hs:23 - Type error in explicitly typed binding *** Term : p *** Type : [Char] -> [(([(Char,[Char])],[(Char,[Char])]),[Char])] *** Does not match : Parser (Char,Char) Hugs> -- Arindam Roy arind_roy@fast-mail.org -- http://www.fastmail.fm - IMAP accessible web-mail

Arindam Roy wrote:
I'm trying to learn Haskell using Hutton's book and Hugs (Sep 06), and am trying to work the parsing examples (chapter 8, Functional parsers), but I can't understand the error I'm seeing when I try to load the program into Hugs.
Following the book, I've defined a Parser type, then written the basic parsers, then a sequencing operator >>=, followed by the example p parser (bottom of page 77). However, trying to load this file in Hugs generates an error (caused by the definition of p).
To make do notation work, you have to (1) use a data type for Parser (instead of a type synonym) and (2) declare that data type an instance of the Monad typeclass. Your code should look something like this: data Parser = Parser (...) instance Monad Parser where return v = ... Parser p >>= f = ... ...
(>>=) :: Parser a -> (a -> Parser b) -> Parser b p >>= f = \inp -> case parse p inp of [] -> [] [(v, out)] -> parse (f v) out
What happens if p returns more then one result? Tillmann

To make do notation work, you have to
(1) use a data type for Parser (instead of a type synonym) and (2) declare that data type an instance of the Monad typeclass.
Your code should look something like this:
data Parser = Parser (...) instance Monad Parser where return v = ... Parser p >>= f = ...
...
Thanks, I'll try this. I haven't read upto the data declaration and inheritance yet, but I'll try it as soon as I have :-)
(>>=) :: Parser a -> (a -> Parser b) -> Parser b p >>= f = \inp -> case parse p inp of [] -> [] [(v, out)] -> parse (f v) out
What happens if p returns more then one result?
The way Parsers are designed in the book, it can't. Parsers always return a list with one element. The only reason the return value is a list is to use the empty list as an error indication. Arindam
participants (2)
-
Arindam Roy
-
Tillmann Rendel