运行text.parsec.indent示例代码出现Couldn't match type类型错误
问题原因
这份示例代码针对indents 0.3.2及更早版本编写,你通过cabal安装的是新版本indents,API存在破坏性变更,直接运行旧代码就会触发类型不匹配错误,核心差异有两点:
- 旧版本
runIndent函数需要传入源文件名作为第一个参数,新版本移除了这个参数 - 旧版本需要手动定义嵌套
State SourcePos的自定义Parser类型、手动组装monad栈,新版本直接提供了IndentParser类型别名,不需要手动叠加monad层
修正方法
只需要调整导入模块、自定义Parser类型定义、iParse函数的实现即可,修正后完整可运行代码如下:
module Main where import Text.Parsec hiding (State) import Text.Parsec.Indent import Control.Monad.Identity -- 直接使用库提供的IndentParser类型,无需手动封装State层 type IParser a = IndentParser String () a -- 移除runIndent的多余源文件名参数 iParse :: IParser a -> SourceName -> String -> Either ParseError a iParse aParser source_name input = runIndent $ runParserT aParser () source_name input input_text :: String input_text = unlines [ "listName:", " item1", " item2", " item3" ] main :: IO () main = do case iParse aNamedList "indented_example" input_text of Left err -> print err Right result -> putStrLn $ "I parsed: " ++ show result data NamedList = NamedList Name [Item] deriving (Show) type Name = String type Item = String aNamedList :: IParser NamedList aNamedList = do b <- withBlock NamedList aName anItem spaces return b aName :: IParser Name aName = do s <- many1 alphaNum _ <- char ':' spaces return s anItem :: IParser Item anItem = do i <- many1 alphaNum spaces return i
替换后运行代码,即可得到预期输出:
I parsed: NamedList "listName" ["item1","item2","item3"]
内容的提问来源于stack exchange,提问作者Iter Ator
相关产品推荐
相关产品推荐

