What is applicative?
It is Monoidal functor:
class Functor f => Monoidal f where
unit :: f ()
(**) :: f a -> f b -> f (a,b)
(<*>) :: f (a -> b) -> f a -> f b
-- The two operators are equivalent:
f <*> a = apply <$> f ** a
where apply (f, a) = f a
a ** b = (,) <$> b <*> a
Law | Proof |
---|---|
Naturality | fmap (f *** g) (u ** v) = fmap f u ** fmap g v |
Left id | unit ** v ≝ v |
Right id | u ** unit ≝ u |
Associativity | u ** (v ** w) ≝ |
Notes:
(***) :: (a -> b) -> (c -> d) -> (a, c) -> (b, d)
f *** g = \(x,y) -> (f x, g y)
≝
refers to isomorphic - f ((), a) is isomorphic to f a.
What is naturality?
It says that if I combine the contexts of 2 applicative functors, then apply functions to the result values
It should be the same as me applying functions to each applicative, then combining them.
Examples of Invalid naturality
Highly contrived example..
Assume monoidal instance for Int, with 1 and (+) as empty and (<>).
fmap _ (Right _) = Left empty
fmap f (Right 2 ** Left 1) = fmap f Left 1
= Left 1
fmap f (Right 2) ** fmap g (Left 1) = Left 1 ** Left 1
= Left 2