假设我有一个带有类型族的类型类:
class MyClass t where
data Fam t :: *
myfun :: t -> Fam t
instance MyClass Int where
newtype Fam Int = Triv Int
myfun = Triv
(与我的实际用例相比,简化了很多,以避免混乱。)
现在,假设我想为可以嵌入到已经是类型类实例的对象中的任何类型提供默认实现。我想我可以写这样的东西:
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
可以直接实现起来相对简单,但是可以想象情况更加复杂。