带有模糊类型的parsec错误

时间:2014-10-24 17:42:18

标签: parsing haskell parsec

我正在使用haskell编写一个wiki解析器,我遇到了这个奇怪的问题。我的代码现在看起来像这样

import System.Environment
import Control.Applicative hiding ((<|>), many)

import Control.Monad
import Text.Parsec
import Text.Parsec.String
import Text.Parsec.ByteString.Lazy

data RichText = UText String
              | DText String
              deriving (Show)

parseBold = do
  string "\'\'\'"
  manyTill anyChar (try (string "\'\'\'"))

parseItalic = do
  string "\'\'"
  manyTill anyChar (try (string "\'\'"))

parsefunc content = do
  case (parse parseItalic "parsing" content) of
    Right result -> return result
    Left error -> return "some error!"

main = do
  content:_ <- getArgs
  result <- parsefunc content
  print result

如果我注释掉parseItalic并使用parseBold,它就可以了。如果我注释掉parseBold并使用parseItalic,它就可以了。 但两者都不能同时工作......它会抛出错误

   No instance for (Stream s0 m0 Char) arising from a use of `string'
   The type variables `s0', `m0' are ambiguous
   Relevant bindings include
     parseBold :: ParsecT s0 u m0 [Char] (bound at wi.hs:13:1)
   Note: there are several potential instances:
     instance Monad m => Stream [tok] m tok
       -- Defined in `Text.Parsec.String'
     instance Monad m =>
              Stream Data.ByteString.Lazy.Internal.ByteString m Char
       -- Defined in `Text.Parsec.ByteString.Lazy'
     instance Monad m =>
              Stream Data.ByteString.Internal.ByteString m Char
       -- Defined in `Text.Parsec.ByteString'
   In a stmt of a 'do' block: string "'''"
   In the expression:
     do { string "'''";
          manyTill anyChar (try (string "'''")) }
   In an equation for `parseBold':
       parseBold
         = do { string "'''";
                manyTill anyChar (try (string "'''")) }

我无法理解这个错误是什么。显然我的类型是一个字符串(这只是[Char]),但为什么编译器抱怨它是Char?

2 个答案:

答案 0 :(得分:1)

您已导入两个

import Text.Parsec.String
import Text.Parsec.ByteString.Lazy

前者解析&#34; Stream Char&#34;而后者&#34;流Word8&#34;。所以你必须摆脱ByteString.Lazy只留下一个变种。如果你需要两者(例如你打算使用多态函数解析ByteString和String),你必须明确地参数化Stream。

答案 1 :(得分:0)

存在歧义错误。

解析器的类型可以是Text.Parsec.String.ParserText.Parsec.ByteString.Lazy.Parser,编译器也不知道选择哪个。

如果添加类型,可以获取要编译的代码....

parseBold::Text.Parsec.ByteString.Lazy.Parser String
parseBold = do
....etc

还有其他方法可以解决歧义......

您可以在推断类型的其他地方使用parseBold / parseItalic,或者您可以清理导入以便只允许一个案例。