首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Haskell解析器,Monad和MonadPlus

Haskell解析器,Monad和MonadPlus
EN

Stack Overflow用户
提问于 2016-03-30 22:26:26
回答 1查看 853关注 0票数 3
代码语言:javascript
复制
    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),并试图更改代码,但我认为我在做一些错误的事情。

我得到的编译错误如下:

代码语言:javascript
复制
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’

编辑//

现在的代码:

代码语言:javascript
复制
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])

错误:

代码语言:javascript
复制
Parser.hs:64:10:
Not in scope: type constructor or class ‘MonadPlus’
EN

回答 1

Stack Overflow用户

发布于 2016-03-30 23:03:55

你可以跟着the migration guide走。这很简单明了:将return的定义移动到pure,添加<*>的样板定义,并从monad实例中删除return

代码语言:javascript
复制
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来说,它只是一个样板文件:

代码语言:javascript
复制
instance Alternative Parser where 
    (<|>) = mplus 
    empty = mzero

作为一个整体的工作代码:

代码语言:javascript
复制
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
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36311809

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档