Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell解析器排序不工作_Haskell_Monads - Fatal编程技术网

Haskell解析器排序不工作

Haskell解析器排序不工作,haskell,monads,Haskell,Monads,我最近一直在工作。我在书中尝试了下面的代码。但它并没有像预期的那样起作用 书上说: >解析p“abcdef” [(('a','c'),“def”)] 但当我尝试它时,它就像: *Main> pp "abcde" [(([('a',"bcde")],[('a',"bcde")]),"abcde")] 排序运算符(+>>=)起作用,但do表示法不起作用。为什么? 这是完整的代码。GHCi 8.2.2 {-# OPTIONS_GHC -fno-warn-tabs #-} type Parse

我最近一直在工作。我在书中尝试了下面的代码。但它并没有像预期的那样起作用

书上说:

>解析p“abcdef”
[(('a','c'),“def”)]

但当我尝试它时,它就像:

*Main> pp "abcde"
[(([('a',"bcde")],[('a',"bcde")]),"abcde")]

排序运算符(+>>=)起作用,但
do
表示法不起作用。为什么?

这是完整的代码。GHCi 8.2.2

{-# OPTIONS_GHC -fno-warn-tabs #-}
type Parser a = String -> [(a, String)]

item :: Parser Char
item = \inp -> case inp of
        [] -> []
        (x:xs) -> [(x, xs)]


parse :: Parser a -> String -> [ (a, String) ]
parse p inp = p inp


return' :: a -> Parser a
return' v = \inp -> [(v,inp)]


(+>>=) :: Parser a -> (a -> Parser b) -> Parser b
p +>>= f = \inp -> case parse p inp of
                    [] -> []
                    [(v, out)] -> parse (f v) out


p :: Parser (Char, Char)
p = item +>>= \x -> 
    item +>>= \_ ->
    item +>>= \y ->
    return' (x,y)


pp = do  x <- item
         item
         y <- item
         return' (x,y)  --return (x,y) this won't work either

我哪里出错了?如何使用do符号编写函数p?

对于编译器,您的
解析器
类型如下所示(不是实际的Haskell语法):

因此,当您将
>=
(由
do
语法调用)用于此类型的操作时,它会出现签名

(>>=) :: ______m______ α -> (α -> ______m______ β) -> ______m______ β
(>>=) :: ((->) String) α -> (α -> ((->) String) β) -> ((->) String) β
i、 e

这不是与
(++>=)
相同的签名–您真正想要的只是

(>>=)  :: __m___ a -> (a -> __m___ b) -> __m___ b
(+>>=) :: Parser a -> (a -> Parser b) -> Parser b
照此看来,使用
>=
您实际上并没有将
解析器
用作monad,相反,
解析器
会将您重定向到另一个monad(函数又称为Reader monad)

要使
解析器
真正像单子一样工作,使用
+>>=
的语义,必须使编译器将其识别为实际的不可分解实体。这意味着,您需要
newtype
而不是
type

newtype Parser a = Parser (String -> [(a, String)])

item :: Parser Char
item = Parser $ \inp -> case inp of
        [] -> []
        (x:xs) -> [(x, xs)]


parse :: Parser a -> String -> [ (a, String) ]
parse (Parser p) inp = p inp


return' :: a -> Parser a
return' v = Parser $ \inp -> [(v,inp)]


(+>>=) :: Parser a -> (a -> Parser b) -> Parser b
Parser p +>>= f = Parser $ \inp -> case parse p inp of
                    [] -> []
                    [(v, out)] -> parse (f v) out


p :: Parser (Char, Char)
p = item +>>= \x -> 
    item +>>= \_ ->
    item +>>= \y ->
    return' (x,y)


pp = do  x <- item
         item
         y <- item
         return' (x,y)
这是一个有点向后的定义——您使用最强大、最特殊的接口(monad)来定义函子类型类的更基本的操作。首选的实例化路径是自顶向下的:

newtype Parser a = Parser (String -> [(a,String)]
  deriving (Functor)

instance Applicative Parser where
  pure v = Parser $ \inp -> [(v,inp)]
  Parser pf <*> Parser px = Parser $
     \inp -> case pf inp of
        [] -> []
        [(f,out)] -> f <$> px out

instance Monad Parser where
  return = pure
  Parser p >>= f = ...
newtype Parser a=Parser(String->[(a,String)]
派生(函子)
实例应用程序解析器,其中
纯v=解析器$\inp->[(v,inp)]
解析器pf Parser px=解析器$
\inp->
[] -> []
[(f,out)]->f px out
实例Monad解析器,其中
返回=纯
解析器p>>=f=。。。

你的
pp
函数中的底层monad是什么?也许你应该给它添加类型签名。顺便说一句,远离
-fno warn tabs
…我对fp很陌生。要理解答案中的概念需要一些时间。谢谢!
(>>=) :: Parser a -> ([(a,String)] -> Parser b) -> Parser b
(>>=)  :: __m___ a -> (a -> __m___ b) -> __m___ b
(+>>=) :: Parser a -> (a -> Parser b) -> Parser b
newtype Parser a = Parser (String -> [(a, String)])

item :: Parser Char
item = Parser $ \inp -> case inp of
        [] -> []
        (x:xs) -> [(x, xs)]


parse :: Parser a -> String -> [ (a, String) ]
parse (Parser p) inp = p inp


return' :: a -> Parser a
return' v = Parser $ \inp -> [(v,inp)]


(+>>=) :: Parser a -> (a -> Parser b) -> Parser b
Parser p +>>= f = Parser $ \inp -> case parse p inp of
                    [] -> []
                    [(v, out)] -> parse (f v) out


p :: Parser (Char, Char)
p = item +>>= \x -> 
    item +>>= \_ ->
    item +>>= \y ->
    return' (x,y)


pp = do  x <- item
         item
         y <- item
         return' (x,y)
instance Functor Parser where
  fmap = liftM  -- makes use of the `Monad` instance below
instance Applicative Parser where
  pure = return'
  (<*>) = ap
instance Monad Parser where
  return = return'
  (>>=) = (+>>=)
newtype Parser a = Parser (String -> [(a,String)]
  deriving (Functor)

instance Applicative Parser where
  pure v = Parser $ \inp -> [(v,inp)]
  Parser pf <*> Parser px = Parser $
     \inp -> case pf inp of
        [] -> []
        [(f,out)] -> f <$> px out

instance Monad Parser where
  return = pure
  Parser p >>= f = ...