I am trying to use the Parsec library to parse a list of Token
values. I'd like to use the token
function in Text.Parsec.Prim to match a single value. It seems like this should work:
type TokenParser a = Parsec [Token] () a
mytoken :: (Token -> Bool) -> TokenParser Token
mytoken test = token showTok posFromTok testTok
where -- and so on
This gives a compile error:
No instance for (Stream [Token] Identity Token)
arising from a use of `Prim.token'
Possible fix:
add an instance declaration for (Stream [Token] Identity Token)
Okay, let's change the type declaration on mytoken:
mytoken :: Stream [Token] Identity Token => (Token -> Bool) -> TokenParser Token
This works, after we add the {-# LANGUAGE FlexibleContexts #-}
extension.
What is going on? First of all, the Stream
class definition in Text.Parsec.Prim has Monad m => Stream [tok] m tok
as one of the instances. Shouldn't Stream [Token] Identity Token
already be covered by that instance? Second, how is it that this is even constraining anything? There are no type variables to be constrained in the type of mytoken
.
Worse yet, when I go to use my new, "constrained" mytoken
in another function, I get exactly the same error, No instance for (Stream [Token] Identity Token) arising from...
It actually necessitates putting the same, seemingly no-op type constraint on the type of the function trying to call mytoken
.
If anyone can help explain to me what this type constraint is doing, I'd be very appreciative.