Reputation: 811
I'm writing a wiki parser using haskell and I have run into this wierd problem. My code right now looks like this
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
If I comment out parseItalic and use parseBold, it works. If I comment out parseBold and use parseItalic, it works. But both don't work at the same time... It throws an error
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 "'''")) }
I'm not able to understand what is this error. Obviously my type is a string (which is nothing but [Char]) but why is the compiler complaining that it is Char?
Upvotes: 0
Views: 555
Reputation: 2005
You have imported both
import Text.Parsec.String
import Text.Parsec.ByteString.Lazy
The former parses "Stream Char" and the latter "Stream Word8". So you have to get rid of ByteString.Lazy
to leave just one variant. If you need both (e.g. you intend to parse ByteString as well as String using polymorphic functions), you have to explicitly parametrise Stream.
Upvotes: 1
Reputation: 12070
There is an ambiguity error.
The type of the parsers can be either Text.Parsec.String.Parser
or Text.Parsec.ByteString.Lazy.Parser
, and the compiler doesn't know which to choose.
You can get the code to compile if you add the types....
parseBold::Text.Parsec.ByteString.Lazy.Parser String
parseBold = do
....etc
There are other ways to fix the ambiguity....
You could use parseBold
/parseItalic
somewhere else where the types would be inferred, or you could clean up the imports so that only one case is allowed.
Upvotes: 1