3

Compiler is GHC 8.6.5. Parsec is 3.1.13.0.

The relevant code is

{-# LANGUAGE FlexibleContexts #-}

import Text.Parsec

-- redundant :: Stream s m Char => ParsecT s u m Char
redundant = upper

ghcmod reports:

• Ambiguous type variables ‘s0’, ‘m0’ arising from a use of ‘upper’
  prevents the constraint ‘(Stream s0 m0 Char)’ from being solved.
  Relevant bindings include
    redundant :: ParsecT s0 u m0 Char
      (bound at T:\empdir\ghc-mod7761\ParD8EE.hs:11:1)
  Probable fix: use a type annotation to specify what ‘s0’,
                                                      ‘m0’ should be.
  These potential instances exist:
    instance [safe] Monad m => Stream [tok] m tok
      -- Defined in ‘Text.Parsec.Prim’
    ...plus four instances involving out-of-scope types
    (use -fprint-potential-instances to see them all)
• In the expression: upper
  In an equation for ‘redundant’: redundant = upper

If I uncomment the type annotation for redundant, however, the code now type checks even despite the fact that the type annotation does not by any means narrow the type of redundant.

It appears to me that the compiler is attempting to substitute some concrete types for s and m when it in fact shouldn't, and is only prevented from doing so when I specify explicitly that s and m are meant to be type variables.

Why would the compiler do so?

fghzxm
  • 1,185
  • 7
  • 19
  • 1
    The first paragraph of [Monomorphism restriction](https://wiki.haskell.org/Monomorphism_restriction) sounds very similar to your description. – Micha Wiedenmann May 28 '19 at 08:12
  • 1
    It is the monomorphism restriction. Your definition is subject to it, as per the conditions explained in the "When does it happen?" section of the answer to the target question. The constraint means GHC won't generalise `s` and `m` (see the "First Rule" section), which in the end leads to the ambiguous type variables error (see "Second Rule"). – duplode May 28 '19 at 09:32

0 Answers0