下面的代码:
{-# LANGUAGE DerivingStrategies #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
class C (f :: Type -> Type) where
g :: String -> f a
class D a where
h :: C f => a -> f a
instance C Maybe where
g _ = Nothing
instance C (Either String) where
g = Left
instance D Int where
h = g . show
newtype NewInt = NewInt Int deriving newtype D
无法编译,错误如下:
Couldn't match representation of type: f Int
with that of: f NewInt
arising from the coercion of the method ‘h’
如果f
做了一些奇怪的类型家族的东西,我想这是有道理的。但是我的f
没有,只有Maybe
和Either
,所以用它的新类型NewInt
替换Int
应该可以工作。
我怎么才能让GHC相信这一点(假设我没有错)。我假设这是一些RoleAnnotations
的东西需要,但我已经尝试过没有工作。
2条答案
按热度按时间qcbq4gxm1#
不幸的是,我们目前还不能指定量化类型变量的角色。我所能想到的最接近的方法是利用安全强制。
请注意超类要求,它或多或少需要一个表示角色,或者更准确地说,它与强制类似。
其余的代码与您的代码相同:
我们必须将
newtype .. deriving
更改为自定义示例,但至少我们可以简单地调用coerce
并让它发挥作用。vwkv1x7d2#
现在在GHC中还不能这样做,你不能给类型变量的参数(比如
f
)给予角色注解。请注意,这对于类型类并不特殊,对于数据类型也会遇到同样的问题: