Paolopast
Paolopast

Reputation: 207

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?

Upvotes: 3

Views: 238

Answers (2)

Thomas M. DuBuisson
Thomas M. DuBuisson

Reputation: 64740

  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.

Upvotes: 3

radrow
radrow

Reputation: 7169

You don't write types explicitly while declaring instances. However, if you really want to do so, turn InstanceSigs extension: {-# LANGUAGE InstanceSigs #-}

As mentioned in another answer, Haskell is indent-sensitive, however you may put definitions in brackets to bypass it:

instance SomeClass Int where {
x = 3
}

Upvotes: 2

Related Questions