Ошибка программы: неопределенный член: >> = Haskell - PullRequest
0 голосов
/ 12 декабря 2018

Я реализую простой интерпретатор в Haskell, но у меня есть эта проблема.Код такой:

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);}

Если я запускаю скрипт в объятиях, все кажется в порядке.Но когда я пытаюсь запустить команду

parse three "abcdef"

, я получаю сообщение об ошибке:

Program error: undefined member: >>=

Пожалуйста, кто-нибудь может мне помочь?

Ответы [ 2 ]

0 голосов
/ 12 декабря 2018

Вы не пишете типы явно при объявлении экземпляров.Однако, если вы действительно хотите это сделать, включите расширение InstanceSigs: {-# LANGUAGE InstanceSigs #-}

Как уже упоминалось в другом ответе, Haskell чувствителен к отступам, однако вы можете поместить определения в скобки, чтобы обойти его:

instance SomeClass Int where {
x = 3
}
0 голосов
/ 12 декабря 2018
  1. Не давать сигнатуры типов экземпляров.

  2. Отступ в определениях экземпляров.

После этих двух вещейвы увидите новую ошибку, вам нужно определить экземпляр Applicative, потому что class Applicative m => Monad m.

РЕДАКТИРОВАТЬ:

Вы писали:

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)

Первая проблема былатип подписи, который я отметил через комментарий выше.Удалите это:

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

Вторая проблема заключалась в отступе.Вы должны сделать отступ в определениях функций-членов (или использовать фигурные скобки, но это необычный стиль):

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

Теперь вы получаете новую ошибку, в которой говорится, что вам нужен аппликативный экземпляр.Поэтому вам понадобится:

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

И даже после этого он скажет вам написать экземпляр для Functor.

...