Парсер Haskell, Monad и MonadPlus

    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) и попытался изменить свой код, но мне кажется, что я здесь что-то не так делаю.

Ошибки компиляции, которые я получаю:

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’

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

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

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’

1 ответ

Вы можете следовать руководству по миграции. Это просто и понятно: перенести определение 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
Другие вопросы по тегам