当泛型实例定义时触发单态

考虑以下:

{-# 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

此代码与GHC 7.8.4一起编译。

当我为T添加一个通用实例(需要FlexibleInstances )时:

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

GHC抱怨:

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

我记得这个问题,但似乎有一些关键的区别。 首先也是最重要的是,GHC没有抱怨预审。 其次,我没有RankNTypes ,这似乎是这个问题的核心问题。 最后,添加NoMonoLocalBinds不起作用。 奇怪的是,加入NoMonomorphismRestriction确实从抱怨更改错误消息fromScalar至约相同的消息fromScalar'

当然,可以通过向fromScalar添加一个类型签名并添加ScopedTypeVariablesfromScalar 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

我愿意承认一些与单形类型有关的东西在这里工作,尽管取消限制并没有帮助。 我的问题是:为什么通过添加一个通用实例触发限制? 更重要的是,为什么GHC试图匹配泛型实例而不是使用T (F r)约束呢? 这似乎是错误的,并且有臭味。


这是GHC错误#10338。 不幸的是,它看起来不会很快得到解决。

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

上一篇: Monomorphism restriction triggered when generic instance defined

下一篇: Which dictionary does GHC choose when more than one is in scope?