haskell - Haskell : Graham Hutton Book-(old-Yellow), Parsing (Ch-8)

标签 haskell compiler-errors

我完全按照本书(第一个版本)中的示例复制了此示例。

书中给出:

p :: Parser (Char,Char)

p =  do x <- item
        item
        y <- item
        return (x,y)

在x上编译错误,为什么?

|
40 | p =  do x <- item
   |         ^^^^^^^^^

:40:9: error:
    * Couldn't match type `([(Char, String)], [(Char, String)])'
                     with `[((Char, Char), String)]'
      Expected type: Parser (Char, Char)
        Actual type: String -> ([(Char, String)], [(Char, String)])
    * In a stmt of a 'do' block: x <- item
      In the expression:
        do x <- item
           item
           y <- item
           return (x, y)
      In an equation for `p':
          p = do x <- item
                 item
                 y <- item
                 ....
(deferred type error)

最佳答案

你是对的。解析器只是函数的别名,因此它使用(->)的Monad实例。这就是为什么您得到String -> ([(Char, String)], [(Char, String)])而不是Parser (Char, Char)String -> [((Char, Char), String)]的原因。

我建议您自己创建一个新类型,并实例化Functor,Applicative和Monad以获得预期的结果。

这将完成工作:

newtype Parser a = Parser { parse :: String -> [(a, String)] }

item :: Parser Char
item = Parser $ \case
  [] -> []
  (c:cs) -> [(c, cs)]

instance Functor Parser where
  fmap f p = Parser $ \s ->
    concatMap (\(a, s) -> [(f a, s)]) $ parse p s

instance Applicative Parser where
  pure a = Parser $ \s -> [(a, s)]
  pf <*> pa = Parser $ \s ->
    concatMap
      (\(f, s') -> fmap (\(a, s'') -> (f a, s'')) (parse pa s'))
      (parse pf s)

instance Monad Parser where
  return a = Parser $ \s -> [(a, s)]
  pa >>= f = Parser $ \s ->
    concatMap (\(a, s') -> parse (f a) s') (parse pa s)

p :: Parser (Char,Char)
p =  do x <- item
        item
        y <- item
        return (x,y)

关于haskell - Haskell : Graham Hutton Book-(old-Yellow), Parsing (Ch-8),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49207052/

相关文章:

haskell - Haskell 中的点管道 ".|"运算符是什么?

haskell - 如何让 GHCi 向我显示不明确的类型签名?

haskell - 在 do block 内迭代

具有许多构造函数的用于 ADT 的 Haskell Zipper

xcode - 从main.mm调用C++库会导致编译错误-验证声明是否与宏冲突

c# - .NET Core 2.1 : AddHsts() and AddHttpsRedirection() not defined

java - 在java中找不到符号,编译时两个.java文件都在同一个目录中

java - 实例化泛型类

haskell - 为什么要进行以下类型检查?

c++ - 如何在 MongoDB C++ 驱动程序中使用 DBClientBase 类插入文档?