mrkkrp/megaparsec

Text.Megaparsec -- Running Parser

funarog opened this issue · 6 comments

Tried to execute the example given in the comments 172-176 in Text.Megaparsec.hs and received an error

Also described on Hackage: Text.Megaparsec Running Parser

λ> import Text.Megaparsec
λ> import qualified Text.Megaparsec.Char.Lexer as L
λ> import Text.Megaparsec.Char
λ> :{
ghci| main = case parse numbers "" "11,2,43" of
ghci| Left bundle -> putStr (errorBundlePretty bundle)
ghci| Right xs -> print (sum xs)
ghci|
ghci| where numbers = L.decimal sepBy char ','
ghci| :}

:35:10-45: error:
• Illegal equational constraint Token s ~ Char
(Use GADTs or TypeFamilies to permit this)
• When checking the inferred type
numbers :: forall {s} {m :: * -> *} {a} {e}.
(Token s ~ Char, Num a, MonadParsec e s m) =>
m [a]
In an equation for ‘main’:
main
= case parse numbers "" "11,2,43" of
Left bundle -> putStr (errorBundlePretty bundle)
Right xs -> print (sum xs)
where
numbers = L.decimal sepBy char ','

:32:33-49: error:
• Ambiguous type variable ‘e0’ arising from a use of ‘errorBundlePretty’
prevents the constraint ‘(ShowErrorComponent
e0)’ from being solved.
Relevant bindings include
bundle :: ParseErrorBundle String e0 (bound at :32:15)
Probable fix: use a type annotation to specify what ‘e0’ should be.
These potential instance exist:
one instance involving out-of-scope types
(use -fprint-potential-instances to see them all)
• In the first argument of ‘putStr’, namely
‘(errorBundlePretty bundle)’
In the expression: putStr (errorBundlePretty bundle)
In a case alternative:
Left bundle -> putStr (errorBundlePretty bundle)

Have you tried enabling GADTs or TypeFamilies as the error message suggests?

Well, I wasn’t trying to debug Text.Megaparsec. I was simply trying to execute the example given in the comments at Running Parser Running parser

I do not recall any Megaparsec tutorial indicating the need for generalized algebraic data types (GADT) or type families extension to support ad-hoc overloading of data types.

main = case parse numbers "" "11,2,43" of
Left bundle -> putStr (errorBundlePretty bundle)
Right xs -> print (sum xs)

numbers = decimal sepBy char ','

Well, indeed one could argue that the example is incomplete because it does not tell the reader which language extensions are necessary for it to work. This information can be added, but then again, there are probably many other details that are usually implicit and trying to mention all of these would be out of scope for the documentation of the library because then it would turn into a Haskell tutorial. You are likely to find that most examples on Hackage (and this is not limited to this library) won't run verbatim, they are rather there to illustrate ideas and patterns of usage. That said, I think a section about the required language extensions is in order on that page.

For the second error (the one complaining about e0) there is a note on the page you link to:

Megaparsec uses some type-level machinery to provide flexibility without compromising on type safety. Thus type signatures are sometimes necessary to avoid ambiguous types. If you're seeing an error message that reads like “Type variable e0 is ambiguous …”, you need to give an explicit signature to your parser to resolve the ambiguity. It's a good idea to provide type signatures for all top-level definitions.

Once again, a type signature like this is omitted in the examples for conciseness.

Mind you I have been through your tutorial several times. There are many examples that are not clear and I am not the first to point this out.

The only solution I can propose here is to report things that are not clear, or even better open PRs to improve the examples and explanations.