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