我正在尝试在Haskell中使用parsec解析字符串,但是每次尝试都会引发另一种类型的错误。
import Text.ParserCombinators.Parsec
csvFile = endBy line eol
line = sepBy cell (char ',')
cell = many (noneOf ",\n")
eol = char '\n'
parseCSV :: String -> Either ParseError [[String]]
parseCSV input = parse csvFile "(unknown)" input
此代码在通过堆栈ghci运行时会产生错误,提示“约束中的非类型变量参数:Text.Parsec.Prim.Stream”
基本上,我想知道Haskell中最直接的方法是基于逗号将String解析为令牌。这似乎是一个非常简单的概念,我认为这将是一次很棒的学习经历,但到目前为止,它只产生了错误。
答案 0 :(得分:1)
在ghci中输入char '\n'
时看到的错误是:
<interactive>:4:1: error:
• Non type-variable argument
in the constraint: Text.Parsec.Prim.Stream s m Char
(Use FlexibleContexts to permit this)
• When checking the inferred type
it :: forall s (m :: * -> *) u.
Text.Parsec.Prim.Stream s m Char =>
Text.Parsec.Prim.ParsecT s u m Char
关于FlexibleContexts
的建议是准确的。您可以像这样打开FlexibleContexts
:
*Main> :set -XFlexibleContexts
不幸的是,下一个错误是• No instance for (Show (Text.Parsec.Prim.ParsecT s0 u0 m0 Char))
(基本上,我们无法打印函数),因此您仍然需要将解析器应用于某些输入才能真正运行它。
就像评论者一样,我发现parseCSV
可以在没有任何语言扩展的情况下使用。
这里发生了一些事情:
在整个程序的上下文中,eol
的类型受parseCSV
上的类型签名的约束。在GHCi中输入eol = char '\n'
时不会发生这种情况。
GHCi的:t
是允许的-它愿意打印一些使用未打开的语言功能的类型。
GHC通过添加大量的language extensions得以增长,程序员可以在每个模块的基础上启用它们。有些已被生产就绪的库广泛使用,有些则是新的和实验性的。