parsinghaskellmonadssequencing

Program error: undefined member: >>= Haskell


I'm implementing a simple interpreter in Haskell but I have this problem. The code is this:

import Control.Applicative
import Data.Char

newtype Parser a = P (String -> [(a,String)])

parse :: Parser a -> String -> [(a,String)]
parse (P p) inp = p inp

item :: Parser Char
item = P (\inp -> case inp of
    [] -> []
    (x:xs) -> [(x,xs)])

instance Functor Parser where
fmap :: (a -> b) -> Parser a -> Parser b
fmap g p = P (\inp -> case parse p inp of
    [] -> []
    [(v,out)] -> [(g v, out)])

instance Monad Parser where
(>>=) :: Parser a -> (a -> Parser b) -> Parser b
p >>= f = P (\inp -> case parse p inp of
    [] -> []
    [(v,out)] -> parse (f v) out)

three :: Parser (Char,Char)
three = do {x <- item;
    item;
    z <- item;
    return (x,z);}

If i run the script in hugs everything seems to be ok. But when I try to run the command

parse three "abcdef"

I get an error:

Program error: undefined member: >>=

Please can someone help me?


Solution

    1. Don't give instances type signatures.

    2. Indent the instance definitions.

    After these two things you'll see a new error, you need to define an Applicative instance because class Applicative m => Monad m.

    EDIT:

    You wrote:

    instance Monad Parser where
    (>>=) :: Parser a -> (a -> Parser b) -> Parser b    -- This is a type signature
    p >>= f = P (\inp -> case parse p inp of   -- This is the definition
        [] -> []
        [(v,out)] -> parse (f v) out)
    

    The first problem was the type signature, which I noted via a comment above. Remove it:

    instance Monad Parser where
    p >>= f = P (\inp -> case parse p inp of   -- This is the definition
        [] -> []
        [(v,out)] -> parse (f v) out)
    

    The second problem was the indentation. You must indent member function defintions (or use curly braces, but that is an uncommon style):

    instance Monad Parser where
        p >>= f = P (\inp -> case parse p inp of
           [] -> []
           [(v,out)] -> parse (f v) out)
    

    Now you get a new error saying you need an applicative instance. So you'd need:

    instance Applicative Parser where
        pure = ...
        (<*>) = ...
    

    And even after that it will tell you to write an instance for Functor.