haskellghcderivingderivingvia# Why is there no `-XDeriveApplicative` extension?

GHC has several useful language extensions for mechanically deriving various common Haskell typeclasses (`-XDeriveFunctor`

, `-XDeriveFoldable`

, `-XDeriveTraversable`

). It seems that `Applicative`

is another class which is often needed and frequently easily derived. For a simple record containing slots of type `a`

, e.g.,

```
data SimpleRecord a = Simple a a a
```

the `Applicative`

instance is trivially derived,

```
instance Applicative SimpleRecord where
pure x = Simple x x x
Simple a1 b1 c1 <*> Simple a2 b2 c2 = Simple (a1 a2) (b1 b2) (c1 c2)
```

Even in the slightly harder case where some `a`

values are buried in other applicative functors, e.g.,

```
data MyRecord f a = MyRecord (f a) a
```

a reasonable instance is easily written,

```
instance (Applicative f) => Applicative (MyRecord f) where
pure x = MyRecord (pure x) x
MyRecord a1 b1 <*> MyRecord a2 b2 = MyRecord (a1 <*> a2) (b1 b1)
```

Why is it that a `-XDeriveApplicative`

extension implementing these sorts of mechanical instances does not exist? Even the `derive`

and `generic-derive`

packages apparently lack `Applicative`

support. Is there a theoretical issue precluding these instances from being usually valid (beyond those reasons that might also threaten the `Functor`

, `Foldable`

, or `Traversable`

extensions)?

Solution

There is at most one instance of `Functor`

for a given data type that follows the functor laws. For example, `map`

is the only lawful implementation of `fmap`

for lists:

```
fmap id == id
fmap (f . g) == fmap f . fmap g
```

But there can be more than one law-abiding instance of `Applicative`

, which isn’t necessarily obvious.

```
pure id <*> v == v
pure (.) <*> u <*> v <*> w == u <*> (v <*> w)
pure f <*> pure x == pure (f x)
u <*> pure y == pure ($ y) <*> u
```

For lists, `<*>`

can behave like `\fs xs -> concatMap (\f -> map f xs) fs`

or like `zipWith ($)`

, and it isn’t clear which one the compiler should choose.

- Comparing lists in Haskell
- Is there a non-identity monad morphism M ~> M that is monadically natural in M?
- Problem with loading module ‘Distribution.Simple’
- Improving efficiency in Stirling numbers calculation
- Does sequencing an infinite list of IO actions by definition result in a never-ending action? Or is there a way to bail out?
- How to call pgQuery from postgresql-query?
- How to avoid whitespace after a tag (link) in Hamlet templates?
- Understanding type-directed resolution in Haskell with existential types
- Why is seq bad?
- Understanding bind function in Haskell
- How to create route that will trigger on any path in Servant?
- How do I use a global state in WAI middleware?
- nixos 23.11 cabal install mysql-simple problem - "Missing (or bad) C libraries"
- Is there a way to kill all forked threads in a GHCi session without restarting it?
- Why can an invalid list expression such as 2:1 be assigned to a variable, but not printed?
- Iterate over a type level list and call a function based on each type in the list
- How does this solution of Project Euler Problem 27 in the Haskell Wiki work?
- Why `Monad` is required to use `pure`?
- Can't do partial function definitions in GHCi
- recommended way to convert Double -> Float in Haskell
- Haskell profiling understanding cost centre summary for anonymous lambda
- Why is Haskell fully declarative?
- GHC Generating Redundant Core Operations
- Question about Event firing in reflex-frp
- Using Haskell's "Maybe", type declarations
- How can I elegantly invert a Map's keys and values?
- Why there is no output for wrapped IO in Haskell?
- What are the definitions of Weather and Memory in xmobar repo?
- Serializing a Data.Text value to a ByteString without unnecessary \NUL bytes
- Using Haskell with VS Code