当泛型实例定义时触发单态
考虑以下:
{-# 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
添加一个类型签名并添加ScopedTypeVariables
来fromScalar
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?