2016-03-30 3 views
2
module Parser where 

import   Control.Monad (MonadPlus, mplus, mzero) 
import   Tagger  (Tag, Token) 


newtype Parser a = Parser ([(Token, Tag)] -> [(a, [(Token, Tag)])]) 

parse :: Parser a -> [(Token, Tag)] -> [(a, [(Token, Tag)])] 
parse (Parser p) = p 

instance Functor Parser where 
    fmap f p = do 
     result <- p 
     return (f result) 

instance Monad Parser where 
    return a = Parser (\cs -> [(a,cs)]) 
    p >>= f = Parser (\cs -> concat [parse (f a) cs' | (a,cs') <- parse p cs]) 

instance MonadPlus Parser where 
    p `mplus` q = Parser (\cs -> parse p cs ++ parse q cs) 
    mzero = Parser (const []) 

{- 

Это мой код для моего анализатора. Видимо, я сделал это «по-старому» и не могу заставить его работать по-новому. Можете ли вы сказать мне, какие вещи мне нужно исправить, чтобы заставить его работать? Я прочитал эту статью (https://wiki.haskell.org/Functor-Applicative-Monad_Proposal) и попытался изменить свой код, но я думаю, что я делаю что-то неправильно здесь.Haskell parser, Monad and MonadPlus

Ошибки Компиляция я получаю:

Parser.hs:56:10: 
    No instance for (Applicative Parser) 
     arising from the superclasses of an instance declaration 
    In the instance declaration for ‘Monad Parser’ 

Parser.hs:60:10: 
    No instance for (GHC.Base.Alternative Parser) 
     arising from the superclasses of an instance declaration 
    In the instance declaration for ‘MonadPlus Parser’ 

EDIT //

Код прямо сейчас:

module Parser where 

import   Control.Applicative 
import   Control.Monad (mplus, mzero, liftM, ap) 
import   Tagger  (Tag, Token) 

-- type Token = String 
-- type Tag = String 

newtype Parser a = Parser ([(Token, Tag)] -> [(a, [(Token, Tag)])]) 

parse :: Parser a -> [(Token, Tag)] -> [(a, [(Token, Tag)])] 
parse (Parser p) = p 

instance Functor Parser where 
    fmap = liftM 

instance Applicative Parser where 
    pure a = Parser (\cs -> [(a,cs)]) 
    (<*>) = ap 

instance Monad Parser where 
    p >>= f = Parser (\cs -> concat [parse (f a) cs' | (a,cs') <- parse p cs]) 

instance MonadPlus Parser where --64 
    p `mplus` q = Parser (\cs -> parse p cs ++ parse q cs) 
    mzero = Parser (const []) 

instance Alternative Parser where 
    (<|>) = mplus 
    empty = mzero 

(+++) :: Parser a -> Parser a -> Parser a 
p +++ q = Parser (\cs -> case parse (p `mplus` q) cs of 
          [] -> [] 
          (x:_) -> [x]) 

Ошибка:

Parser.hs:64:10: 
Not in scope: type constructor or class ‘MonadPlus’ 
+0

Вы можете следовать руководству по миграции: https: //ghc.h askell.org/trac/ghc/wiki/Migration/7.10 – zakyggaps

+0

Думаю, вам все еще нужны ручные экземпляры для аппликативного (что будет очень просто) и альтернативы. –

+0

Спасибо за предложения! @zakyggaps Я пробовал следовать инструкциям по вашей ссылке, но, к сожалению, теперь есть новые ошибки, которые я не уверен, как я должен это исправить. Мне, наверное, все-таки нужно что-то изменить? – katyp

ответ

3

Вы можете следить за the migration guide. Это просто и понятно: переместить определение return к pure, добавьте определение шаблонного из <*> и удалить return из монады Например:

instance Functor Parser where 
    fmap = liftM 

instance Applicative Parser where 
    pure a = Parser (\cs -> [(a,cs)]) 
    (<*>) = ap 

instance Monad Parser where 
    p >>= f = Parser (\cs -> concat [parse (f a) cs' | (a,cs') <- parse p cs]) 

Для Alternative это шаблонный и больше ничего:

instance Alternative Parser where 
    (<|>) = mplus 
    empty = mzero 

рабочий код в целом:

module Parser where 

import   Control.Monad 
import   Tagger  (Tag, Token) 
import   Control.Applicative 

newtype Parser a = Parser ([(Token, Tag)] -> [(a, [(Token, Tag)])]) 

parse :: Parser a -> [(Token, Tag)] -> [(a, [(Token, Tag)])] 
parse (Parser p) = p 

instance Functor Parser where 
    fmap = liftM 

instance Applicative Parser where 
    pure a = Parser (\cs -> [(a,cs)]) 
    (<*>) = ap 

instance Monad Parser where 
    p >>= f = Parser (\cs -> concat [parse (f a) cs' | (a,cs') <- parse p cs]) 

instance MonadPlus Parser where 
    p `mplus` q = Parser (\cs -> parse p cs ++ parse q cs) 
    mzero = Parser (const []) 

instance Alternative Parser where 
    (<|>) = mplus 
    empty = mzero 
+0

Так что же такое «а» в определении «чистый»? –

+1

@PaulJohnson Извините, исправлено. – zakyggaps

+0

Это исправление дает только ошибку «Parser.hs: 56: 29: Не в области:« a », теперь, кажется, какая-то проблема с pure = Parser (\ cs -> [(a, cs) ]) или что-то? Я очень новичок в этом и не знаю, где корень проблемы. – katyp

Смежные вопросы