monadとかapplicativeとか

なんとなくメモ

An Applicative is a Monoid in the category of endofunctors, what's the problem?

monadとかapplicativeとか、めっちゃ役にたつのってなんでだろうと考えてみた。

ようは、関数fとかgとかがあって、それを合成して何かプログラムができたとしよう。
機能拡張をmとする。そうすると fはm fになる。
機能拡張mを考えた時に、構造を維持したいよね。
それを可能にするのがfunctor則。
m (f.g)=(m f).(m g)

haskellだと

class Functor m where
fmap :: (a -> b) -> m a -> m b

とかく。これを<$>とも書く。fmap f x = f <$> x

さて、Functor mだけど、以下の性質をもっていると便利そうだ。
1 mの合成があれば、便利そうだ。
2 mの合成をする度にインターフェースが代わってしまうのは不便。インターフェースがかわっても、データのやり取りができる機能が欲しい。

これをかなえるのがapplicativeになる。
1のmの合成は Day convolution ★で与える。まあ、何か構成方法があるとみなせばよい。
2をかなえるのが、自然変換unitとjoinになる。

つまり、Day convolution ★はunitとjoinがきまるように定める。
さて、applicativeは、

class Functor m => Applicative m where
pure :: a -> m a
(<*>) :: m (a -> b) -> m a -> m b

で定められている。pureはそのままunitになる。

Day convolution ★は

Day :: f (a -> b) -> g a -> Day f g b

で定めれていて、

(<*>) :: Applicative f => f (a -> b) -> f a -> f b

をもちいて、

Day (<*>) :: Day f f b -> f b

が定まれば、joinを持つことになる。

もちろん、勝手にpureと<*>を決めて今述べたことが成立するわけがないので、次を要請する。

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

Day convolution ★は、この構成方法より、 (<*>) より決まる。


monadは、もっと簡単だ。Day convolution★は素朴にFunctorを合成したものになる。

このとき、モナド則を

(return x) >>= f ≡ f x
m >>= return ≡ m

で決める。
joinとbind (>>=)は互いに導出できる。

join n = n >>= id
m >>= g ≡ join (fmap g m)

monadがDay convolution★の特別な場合であることから分かるように、Applicativeはmonadの一般化になっている。


http://www.fceia.unr.edu.ar/~mauro/pubs/Notions_of_Computation_as_Monoids.pdf
Monads Made Difficult
Where do the applicative laws come from? : haskell
Monad (functional programming) - Wikipedia
Monads Made Difficult