使用类型族的强制功能会导致约束错误

时间:2018-12-03 15:27:28

标签: haskell

假设我有一个带有类型族的类型类:

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可以直接实现起来相对简单,但是可以想象情况更加复杂。

0 个答案:

没有答案