3

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?

Paolopast
  • 197
  • 1
  • 11

2 Answers2

3
  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.

Paul Johnson
  • 17,438
  • 3
  • 42
  • 59
Thomas M. DuBuisson
  • 64,245
  • 7
  • 109
  • 166
  • I'm quite new to this linguage. I'm trying to understand what is described in the book "Programming in haskell". Can you please give me an example of what you said? – Paolopast Dec 12 '18 at 15:37
  • @paolopast Sure, see my edit. The book you're following is likely old if it didn't tell you to write Applicative and Functor instances. – Thomas M. DuBuisson Dec 12 '18 at 15:46
  • I'm getting "Syntax error in expression (unexpected `}', possibly due to bad layout)". But there are not '}' – Paolopast Dec 12 '18 at 15:56
  • I just solved. It was a problem of indentation. But now it tells me to implement the return function. I will check on the book. Thank you so much!! – Paolopast Dec 12 '18 at 16:00
  • @Paolopast yup, `return` is the function that puts a value "into" your monad. In this case, probably `return x = P $ \str -> [(x, str)]`. But also, you will need `pure` with the same definition. (`pure` == `return`). – Paul Johnson Dec 14 '18 at 08:41
  • For more on `Applicative`, see https://stackoverflow.com/questions/2395697/what-is-lifting-in-haskell/2395956#2395956 – Paul Johnson Dec 14 '18 at 08:44
2

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
}
radrow
  • 6,419
  • 4
  • 26
  • 53