12

I'm not really sure what I'm doing wrong here:

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)

So far, so normal (Additive is defined in the algebra package but is pretty self-explanatory).

However, now I want to be clever using DerivingVia and StandaloneDeriving and I can't even get the next line to compile

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

But that gets me

    * 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)'

Can anyone tell me what I'm doing wrong? I'm running GHC 8.6.2

Iceland_jack
  • 6,848
  • 7
  • 37
  • 46
Julian Birch
  • 2,605
  • 1
  • 21
  • 36
  • 1
    For what it is worth, I prefer your syntax with `via ...` at the end to the one actually accepted by GHC, where `via` comes earlier. – chi Nov 21 '18 at 19:50

1 Answers1

25

It's

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

The way you wrote it, via looks like a type variable

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

and this produces a kind-mismatch error, as Additive (Square a) :: Constraint is already saturated, but you have applied it to two more arguments.

This is backwards from the shorthand form:

data T' = ...
  deriving Class via T 
HTNW
  • 27,182
  • 1
  • 32
  • 60
  • Is this anywhere in the users' guide? I haven't been able to find it! – dfeuer Mar 21 '19 at 02:22
  • 1
    [It is here](https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/glasgow_exts.html#deriving-strategies). It says, in general, *all* strategies look like `deriving strat instance head`, and `via _` is one example of a strategy. – HTNW Mar 21 '19 at 05:30
  • 1
    Hmmm. That takes a lot more reading between the lines than it should. Maybe I'll remember to submit a PR to improve the docs. – dfeuer Mar 21 '19 at 05:43