使用Parsec解析字符串?

时间:2018-10-18 17:36:53

标签: parsing haskell parsec

我正在尝试在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解析为令牌。这似乎是一个非常简单的概念,我认为这将是一次很棒的学习经历,但到目前为止,它只产生了错误。

1 个答案:

答案 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得以增长,程序员可以在每个模块的基础上启用它们。有些已被生产就绪的库广泛使用,有些则是新的和实验性的。