5

Given a type, there is only one obvious way to implement an Additive instance, from the Linear library, to it. Conveniently, Additive has a generic implementation, so we can use deriving for it. Unfortunately, it depends on the existence of an Applicative instance, which is not derivable, so you still have to declare it:

{-# LANGUAGE DeriveGeneric, DeriveFunctor #-}

import Linear
import GHC.Generics
import Control.Applicative

data Foo a = Foo a a a deriving (Show, Functor, Generic1)

instance Additive Foo

instance Applicative Foo where
    pure x = Foo x x x
    Foo f g h <*> Foo x y z = Foo (f x) (g y) (h z)

main = print $ Foo 1 2 3 ^+^ Foo 4 5 6

Is there any way to derive Additive automatically, without having to declare an Applicative instance?

duplode
  • 33,731
  • 7
  • 79
  • 150
MaiaVictor
  • 51,090
  • 44
  • 144
  • 286
  • In next version of base 4.17.0.0, `GHC.Generics` will add a newtype called `Generically1`. This has an `Applicative` instance for any generic product type constructor. `data Foo a = Foo a a a deriving stock Generic1 deriving (Functor, Applicative) via Generically1 Foo`. – Iceland_jack Jul 16 '22 at 17:16

1 Answers1

1

No.

The canonical example of a datatype which has two perfectly cromulent Applicative instances is [] / ZipList. This proves that a generic derivation of Applicative for [] would need to somehow choose one or the other, when in fact neither choice is more valid than the other.

Cactus
  • 27,075
  • 9
  • 69
  • 149