haskellderivingderivingvia# Can I use DerivingVia to derive instances for data types isomorphic to tuples

Given the following data type

```
data Both a b = Both { left :: a, right :: b }
```

I can write instances for Applicative etc. like so (omitting Functor here as we can use `DeriveFunctor`

):

```
instance Monoid a => Applicative (Both a) where
pure x = Both mempty x
Both u f <*> Both v x = Both (u <> v) (f x)
```

Since `Both`

is isomorphic to `(a,b)`

, I'm wondering whether I can use `DerivingVia`

to derive the instance:

```
data Both a b = ... deriving Applicative via ((,) a)
```

which results in error messages like:

```
• Couldn't match representation of type ‘(a, a1)’
with that of ‘Both a a1’
arising from the coercion of the method ‘pure’
from type ‘forall a1. a1 -> (a, a1)’
to type ‘forall a1. a1 -> Both a a1’
• When deriving the instance for (Applicative (Both a))
```

which I interpret as "the compiler doesn't know how to turn `Both`

into `(,)`

". How do I tell the compiler to do that using *the obvious way*?

I've seen this question and the answers, but I'm hoping for a solution that requires less boilerplate.

Solution

Inspired by this answer, and with the help of the `generic-data`

package one can write:

```
{-# LANGUAGE DeriveGeneric, DerivingStrategies, DerivingVia #-}
import GHC.Generics
import Generic.Data
data Both a b = Both {left :: a, right :: b}
deriving stock (Generic1)
deriving (Functor, Applicative) via Generically1 (Both a)
```

- 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