简体   繁体   中英

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?

  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.

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
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM