代码之家  ›  专栏  ›  技术社区  ›  Julian Birch

通过独立派生

  •  3
  • Julian Birch  · 技术社区  · 7 年前

    我不太确定我在这里做错了什么:

    data Vector2D u = Vector2D { 
        _x :: u, 
        _y :: u 
    } deriving stock (Show, Eq, Functor, Foldable, Traversable)
    
    {-# INLINE addVector2 #-}
    addVector2 :: (Additive a) => Vector2D a -> Vector2D a -> Vector2D a 
    addVector2 (Vector2D { _x = x1, _y = y1 }) (Vector2D { _x = x2, _y = y2 }) = 
        Vector2D { _x = x1 + x2, _y = y1 + y2 }
    
    instance (Additive a) => Additive (Vector2D a) where
        (+) = addVector2
    
    newtype Square a = Square {
        unpackSquare :: Vector2D a
    } deriving stock (Show, Eq)
    

    到目前为止,一切都是正常的(加法在代数包中定义,但很容易解释)。

    不过,现在我想巧妙地使用派生VIA和Standalonederiving,甚至无法编译下一行

    deriving instance (Additive a) => Additive (Square a) via (Vector2D a)
    

    但这让我

        * Expected kind `k0 -> * -> Constraint',
            but `Additive (Square a)' has kind `Constraint'
        * In the stand-alone deriving instance for
            `(Additive a) => Additive (Square a) via (Vector2D a)'
    

    有人能告诉我我做错了什么吗?我在运行GHC 8.6.2

    1 回复  |  直到 7 年前
        1
  •  9
  •   HTNW    7 年前

    它是

    deriving via (Vector2D a) instance (Additive a) => Additive (Square a)
    

    你写的方式, via 看起来像一个类型变量

    deriving instance (Additive a) => Additive (Square a) via (Vector2D a)
    -- <==>
    deriving instance forall a via. (Additive a) => Additive (Square a) (via) (Vector2D a)
    

    这会产生一种失配误差,比如 Additive (Square a) :: Constraint 已经饱和,但您已经将其应用于另外两个参数。

    这与速记形式相反:

    data T' = ...
      deriving Class via T 
    
    推荐文章