我正在使用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?
答案 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.Parser
或Text.Parsec.ByteString.Lazy.Parser
,编译器也不知道选择哪个。
如果添加类型,可以获取要编译的代码....
parseBold::Text.Parsec.ByteString.Lazy.Parser String
parseBold = do
....etc
还有其他方法可以解决歧义......
您可以在推断类型的其他地方使用parseBold
/ parseItalic
,或者您可以清理导入以便只允许一个案例。