Monomorphism restriction triggered when generic instance defined

Consider the following:

{-# LANGUAGE TypeFamilies, FlexibleContexts, GADTs, MultiParamTypeClasses #-}

type family F r

class (Functor t) => T t r where
  fromScalar :: r -> t r

data Foo t r where
  Foo :: t (F r) -> Foo t r
  Scalar :: r -> Foo t r

toF :: r -> F r
toF = undefined

convert :: (T t (F r))
  => Foo t r -> Foo t r
convert (Scalar c) = 
  let fromScalar' = fromScalar
  in Foo $ fromScalar' $ toF c

This code compiles with GHC 7.8.4.

When I add a generic instance for T (which requires FlexibleInstances ):

instance (Functor t, Num r) => T t r

GHC complains:

Could not deduce (Num (F r)) arising from a use of ‘fromScalar’
    from the context (T t (F r))
      bound by the type signature for
                 convert :: (T t (F r)) => Foo t r -> Foo t r
      at Main.hs:(17,12)-(18,23)
    In the expression: fromScalar
    In an equation for ‘fromScalar'’: fromScalar' = fromScalar
    In the expression:
      let fromScalar' = fromScalar in Foo $ fromScalar' $ toF c

I remembered this question, but there seem to be some key differences. First and most important, GHC didn't complain pre-instance. Second, I don't have RankNTypes , which seemed to be at the core of the problem with that question. Finally, adding NoMonoLocalBinds doesn't help. Strangely, adding NoMonomorphismRestriction does change the error message from complaining about fromScalar to the same message about fromScalar' .

Of course the problem can be fixed by adding a type signature to fromScalar and adding ScopedTypeVariables :

convert :: forall t r . (T t (F r))
  => Foo t r -> Foo t r
convert (Scalar c) = 
  let fromScalar' = fromScalar :: F r -> t (F r)
  in Foo $ fromScalar' $ toF c

I'm willing to concede something screwy with monomorphic types is at work here, even though removing the restrictions didn't help. My question is: why is the restriction triggered by the addition of a generic instance? More importantly, why does GHC try to match the generic instance instead of using the T (F r) constraint? That seems plain wrong, and smells of this bug.


This is GHC bug #10338. Unfortunately it doesn't look like it's going to get resolved anytime soon.

链接地址: http://www.djcxy.com/p/43264.html

上一篇: GHC不会选择唯一可用的实例

下一篇: 当泛型实例定义时触发单态