Haskell 使用类型族强制函数会导致约束错误
假设我有一个类型类和一个类型族:Haskell 使用类型族强制函数会导致约束错误,haskell,Haskell,假设我有一个类型类和一个类型族: class MyClass t where data Fam t :: * myfun :: t -> Fam t instance MyClass Int where newtype Fam Int = Triv Int myfun = Triv (与我的实际用例相比,简化了很多,以避免混乱。) 现在假设我想为任何类型提供一个默认实现,该类型可以嵌入到已经是type类实例的对象中。我想我可以这样写: class (MyC
class MyClass t where
data Fam t :: *
myfun :: t -> Fam t
instance MyClass Int where
newtype Fam Int = Triv Int
myfun = Triv
(与我的实际用例相比,简化了很多,以避免混乱。)
现在假设我想为任何类型提供一个默认实现,该类型可以嵌入到已经是type类实例的对象中。我想我可以这样写:
class (MyClass (Embed t)) => Embeddable t where
type Embed t :: *
embed :: t -> Embed t
newtype MyNewtype t = MyConstructor t
instance (Embeddable t) => MyClass (MyNewtype t) where
newtype Fam (MyNewtype t) = MyFam (Fam (Embed t))
myfun (MyConstructor x) = MyFam (myfun . embed $ x)
myfunDef :: forall t. (Coercible (Fam (MyNewtype t)) (Fam t)) => t -> Fam t
myfunDef = coerce (myfun :: MyNewtype t -> Fam (MyNewtype t))
问题是,这不会编译:
• Could not deduce: Embed t ~ t arising from a use of ‘coerce’
from the context: Coercible (Fam (MyNewtype t)) (Fam t)
bound by the type signature for:
myfunDef :: forall t.
Coercible (Fam (MyNewtype t)) (Fam t) =>
t -> Fam t
at src/Lib.hs:22:1-75
‘t’ is a rigid type variable bound by
the type signature for:
myfunDef :: forall t.
Coercible (Fam (MyNewtype t)) (Fam t) =>
t -> Fam t
at src/Lib.hs:22:1-75
• In the expression:
coerce (myfun :: MyNewtype t -> Fam (MyNewtype t))
In an equation for ‘myfunDef’:
myfunDef = coerce (myfun :: MyNewtype t -> Fam (MyNewtype t))
• Relevant bindings include
myfunDef :: t -> Fam t (bound at src/Lib.hs:23:1)
|
23 | myfunDef = coerce (myfun :: MyNewtype t -> Fam (MyNewtype t))
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
我不明白为什么会有这个错误,也不知道如何解决它
如果它已编译,我本打算这样使用它:
instance Embeddable Bool where
type Embed Bool = Int
embed False = 0
embed True = 1
instance MyClass Bool where
newtype Fam Bool = BoolFam (Fam (Embed Bool))
myfun = myfunDef
显然,在这种情况下,
MyClass Bool
直接实现起来相对简单,但想象一下,在一个更复杂的情况下。这听起来像一个GHC bug。无法推断:Embed t~t
:您希望它保持不变吗?您没有任何可嵌入的实例,也没有任何约束要求它保持。同样,在您建议的嵌入式Bool
实例中,它不适用<代码>(强制(Fam(MyNewtype t))(Fam t))
约束myfunDef
我认为需要一个无限类型MyNewtype t~t
。数据族是内射的。我不希望Embed t~t
保持不变,但我不明白为什么它需要保持不变。在我建议的MyClass Bool
实例中,Fam Bool
应表示为Fam(嵌入Bool)
,即Fam Int
;而Fam(MyNewtype Bool)
也应表示为Fam(Embed Bool)
;所以我认为他们会互相强迫。