fridofrido•

I think you have a few bits mixed up in your head here: namely the Parsec monad, the Identity monad.

char 'a' has an overly polymorphic type, but to specialize it a bit, in this case it will be ParsecT Void Text m for any monad m (the idea is that you use it in a so called "monad transformer stack"), and then specializing even more, ParsecT Void Text Identity. Here Identity is a parameter of the type ParsecT, which it can use internally however it wants.

So this is wrong:

In our case m is Identity

because m is in fact ParsecT Void Text Identity instead.

If you look up MonadParsec e s m it's quite complicated, but Identity is not an instance (and cannot be because it doesn't support the parsec operations).

In summary, the m in MonadParsec e s m (a type class) and in ParsecT e s m a (a type constructor) are different m-s, and the whole latter will play the role of m in the first one.

2
MachineGunPabloOP•

Thank you very much!

Yes, now I see that I was completely mixing up the type variable in ParsecT type constructor, and the one in the MonadParser type class. In the context of char, m is clearly Parser and not Identity, as I thought.

In my defense, the tutorial does have a mistake in this regard which greatly added to my confusion:

The :: Parser Char annotation is necessary because satisfy by itself is polymorphic, so parseTest cannot know what to use in place of e and s in MonadParsec e s m (m is assumed to be Identity with these helpers).

Thank you again for your help!

1