## Logistic is to setters as Distributive is to getters

Distributive functors are containers where getters can be enumerated as their own types.

This is the definition of the `Distributive`

class:

```
class Functor g => Distributive g where
distribute :: Functor f => f (g a) -> g (f a)
```

One easy-to-understand instance is `Complex`

.

```
data Complex a = !a :+ !a
realPart :: Complex a -> a
realPart (x :+ _) = x
imagPart :: Complex a -> a
imagPart (_ :+ y) = y
instance Distributive Complex where
distribute wc = fmap realPart wc :+ fmap imagPart wc
```

Given any functor-wrapped value, `distribute`

fmaps the getters of `Complex`

to it.
`distribute id`

instantiates it as the function (`(->) r`

) functor. In this case, `distribute id`

is equal to `realPart :+ imagPart`

.

However, we cannot modify the elements this way because `distribute`

passes getters but not setters.

Here we introduce a new `Logistic`

class to provide settability to containers:

```
class Functor t => Logistic t where
deliver :: Contravariant f => f (t a -> t a) -> t (f (a -> a))
```

While the type of `deliver`

is slightly more intimidating, it’s actually very close to the `distribute`

;
the `Functor`

constraint is `Contravariant`

instead and the contents are endomorphisms.

Here’s the instance for `Complex`

. `deliver f`

contramaps a setter function to `f`

for each field:

```
instance Logistic Complex where
deliver f
= contramap (\g (a :+ b) -> g a :+ b) f
:+ contramap (\g (a :+ b) -> a :+ g b) f
```

Instantiating the `Op`

contravariant functor, it is trivial to obtain a collection of setters.

```
newtype Op a b = Op { getOp :: b -> a }
setters :: Logistic t => t ((a -> a) -> t a -> t a)
setters = getOp <$> deliver (Op id)
```

```
ghci> let setR :+ setI = setters
ghci> setR (+1) (0 :+ 1)
1 :+ 1
ghci> setI (+1) (0 :+ 1)
0 :+ 2
```

`deliver`

has a generic default implementation which works for any single-constructor products.

This class can be useful to complement `Distributive`

. Generalisation to higher-kinded data would also be interesting.