我想学习如何Parse an Indentation-Sensitive Language,但我得到Couldn't match type
错误。
我安装了由cabal install parsec
和cabal 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 }
我不知道为什么我会得到这些错误,我使用了完全相同的示例代码。我做错了什么?
1条答案
按热度按时间bvjveswy1#
该教程是在0.4.0.0
indents
的www.example.com版本发布之前编写的,该版本做了很多突破性的更改。请降级到indents-0.3.3
以使其按编写的那样工作。