haskellghcimonomorphism-restriction

List of Existentially Quantified Constructors


I have the following data type:

{-# LANGUAGE ExistentialQuantification #-}
{-# LANGUAGE ExtendedDefaultRules #-}

class ToString a where

data M = forall a. (ToString a) => B a

In GHCI I can do the following with no problems:

let bs = [B, B]

But if I try to do this in a compiled file, I get the following error:

No instance for (ToString a0) arising from a use of ‘B’
The type variable ‘a0’ is ambiguous
Relevant bindings include
  bs :: [a0 -> M] (bound at src/My/Module:7:1)

Which extension(s) am I missing that would allow me to create the list of B as shown? Or what am I missing that GHCI is adding?


Solution

  • This is because GHCi doesn't turn on the monomorphism restriction, and GHC (by default) does. To witness, the following file typechecks:

    {-# LANGUAGE ExistentialQuantification #-}
    {-# LANGUAGE NoMonomorphismRestriction #-}
    
    class ToString a where
    
    data M = forall a. (ToString a) => B a
    
    bs = [B, B]
    

    The inferred type of bs is fairly useless, of course:

    *Main> :t bs
    bs :: ToString a => [a -> M]
    

    If you don't want to turn off the monomorphism restriction, you can just add a type signature to the definition of bs:

    {-# LANGUAGE ExistentialQuantification #-}
    
    class ToString a where
    
    data M = forall a. (ToString a) => B a
    
    bs :: (ToString a) => [a -> M]
    bs = [B, B]