haskell 运行text.parsec.indent示例时出现无法匹配类型错误

omhiaaxx  于 2022-11-14  发布在  其他
关注(0)|答案(1)|浏览(113)

我想学习如何Parse an Indentation-Sensitive Language,但我得到Couldn't match type错误。
我安装了由cabal install parseccabal install indents依赖的,并尝试运行此示例代码:

module Main where

-- First, import all the needed modules.

import Text.Parsec hiding (State)
import Text.Parsec.Indent
import Control.Monad.State

-- Next, define our new Parser type. This replaces the Identity monad
-- with the (State SourcePos) monad.

type IParser a = ParsecT String () (State SourcePos) a

-- Now we define our new parse function. This one accepts an IParser
-- (which we've just defined) instead of a Parser.

iParse :: IParser a -> SourceName -> String -> Either ParseError a
iParse aParser source_name input =
  runIndent source_name $ runParserT aParser () source_name input

-- Define our sample input string. Note: the unlines function joins
-- strings together with newline characters.

input_text :: String
input_text = unlines [
    "listName:",
    "  item1",
    "  item2",
    "  item3"
  ]

-- Define main. It parses the input text and prints the parsed value. If
-- there was an error, it prints the error.

main :: IO ()
main = do
  case iParse aNamedList "indented_example" input_text of
    Left  err    -> print err
    Right result -> putStrLn $ "I parsed: " ++ show result

-- Define a datatype to hold our parsed value.

data NamedList = NamedList Name [Item]
  deriving (Show)

-- Define what we mean by 'Name' and 'Item'. In this case, they are both
-- strings.

type Name = String
type Item = String

-- Define how we parse a NamedList. A Named list is a Name and a list of
-- Items contained in the NamedList data structure. Read more about the
-- withBlock function here:

-- http://hackage.haskell.org/packages/archive/indents/0.3.2/doc/html/Text-Parsec-Indent.html#v:withBlock

aNamedList :: IParser NamedList
aNamedList = do
  b <- withBlock NamedList aName anItem
  spaces
  return b

-- A name is an alpha-numeric string followed by a ':' and some
-- whitespace.

aName :: IParser Name
aName = do
  s <- many1 alphaNum
  _ <- char ':'
  spaces
  return s

-- An item is an alpha-numeric string followed by some whitespace.

anItem :: IParser Item
anItem = do
  i <- many1 alphaNum
  spaces
  return i

-- Output:
--  > runhaskell -Wall indented_parsec_example.hs
--  I parsed: NamedList "listName" ["item1","item2","item3"]

我得到这个错误:

Main.hs:19:13: error:
    * Couldn't match type `[Char]'
                     with `Control.Monad.Trans.Reader.ReaderT
                             Text.Parsec.Indent.Internal.Indentation
                             Data.Functor.Identity.Identity
                             (State SourcePos (Either ParseError a) -> Either ParseError a)'
      Expected type: IndentT
                       Data.Functor.Identity.Identity
                       (State SourcePos (Either ParseError a) -> Either ParseError a)
        Actual type: SourceName
    * In the first argument of `runIndent', namely `source_name'
      In the expression: runIndent source_name
      In the expression:
        runIndent source_name $ runParserT aParser () source_name input
    * Relevant bindings include
        aParser :: IParser a (bound at Main.hs:18:8)
        iParse :: IParser a -> SourceName -> String -> Either ParseError a
          (bound at Main.hs:18:1)

Main.hs:60:8: error:
    * Couldn't match type `Control.Monad.Trans.Reader.ReaderT
                             Text.Parsec.Indent.Internal.Indentation m0'
                     with `StateT SourcePos Data.Functor.Identity.Identity'
      Expected type: ParsecT String () (State SourcePos) NamedList
        Actual type: IndentParserT String () m0 NamedList
    * In a stmt of a 'do' block: b <- withBlock NamedList aName anItem
      In the expression:
        do { b <- withBlock NamedList aName anItem;
             spaces;
             return b }
      In an equation for `aNamedList':
          aNamedList
            = do { b <- withBlock NamedList aName anItem;
                   spaces;
                   return b }

Main.hs:60:28: error:
    * Couldn't match type `StateT
                             SourcePos Data.Functor.Identity.Identity'
                     with `Control.Monad.Trans.Reader.ReaderT
                             Text.Parsec.Indent.Internal.Indentation m0'
      Expected type: IndentParserT String () m0 Name
        Actual type: IParser Name
    * In the second argument of `withBlock', namely `aName'
      In a stmt of a 'do' block: b <- withBlock NamedList aName anItem
      In the expression:
        do { b <- withBlock NamedList aName anItem;
             spaces;
             return b }

Main.hs:60:34: error:
    * Couldn't match type `StateT
                             SourcePos Data.Functor.Identity.Identity'
                     with `Control.Monad.Trans.Reader.ReaderT
                             Text.Parsec.Indent.Internal.Indentation m0'
      Expected type: IndentParserT String () m0 Item
        Actual type: IParser Item
    * In the third argument of `withBlock', namely `anItem'
      In a stmt of a 'do' block: b <- withBlock NamedList aName anItem
      In the expression:
        do { b <- withBlock NamedList aName anItem;
             spaces;
             return b }

我不知道为什么我会得到这些错误,我使用了完全相同的示例代码。我做错了什么?

bvjveswy

bvjveswy1#

该教程是在0.4.0.0indents的www.example.com版本发布之前编写的,该版本做了很多突破性的更改。请降级到indents-0.3.3以使其按编写的那样工作。

相关问题