2006-12-07 [長年日記]
λ. Applicative Programming with Effects by Conor McBride and Ross Paterson
Monad(Strong Monad)とArrowの間に位置する抽象化だとか、コンビネータのSとKを抽象化したものとかいう話は耳にしてたけど、期待していたよりも面白かった。以前に書いた行列のコードなんかは、これを使って整理できそうだ。
圏論の言葉でいうと Applicative は strong lax monoidal functor になっているということなのだが、(モナドでない)一般の関手の場合のstrengthの「standard equations」なんて知りませんから!(後で調べる)
<2007-03-04追記>
standard equations は
と
の二つだろう
</2007-03-04追記>
それから「Note that B and FC swap places in the above diagram: strong naturality implies commutativety with pure computations.」という部分を理解するのにちと苦労した。
あと、最後のexerciseの「fmap swap (pure x ★ u) = u ★ pure x」の証明が案外面倒だった。もっと短く出来ないかな。
[lemma] pure (f . g) <*> x = {- homomorphism -} pure (.) <*> pure f <*> pure g <*> x = {- composition -} pure f <*> (pure g <*> x) fmap swap (pure x ★ u) = {- definition of ★ -} fmap swap (pure (,) <*> pure x <*> u) = {- homomorphism -} fmap swap (pure ((,) x) <*> u) = {- definition of fmap -} pure swap <*> (pure ((,) x) <*> u) = {- lemma -} pure (swap . ((,) x)) <*> u = pure (\y -> swap (x,y)) <*> u = pure (\y -> (y,x)) <*> u = pure (\y -> (\f -> f x) ((,) y)) <*> u = pure ((\f -> f x) . (,)) <*> u = {- lemma -} pure (\f -> f x) <*> (pure (,) <*> u) = {- interchange -} pure (,) <*> u <*> pure x = {- definition of ★ -} u ★ pure x
いや、「The Monoidal laws and the above definition of pure
imply that pure computations commute past effects: fmap swap (pure x ★ u)
= u ★ pure x
」と言っているのだから、Applicativeの性質からではなく strong lax monoidal functor の性質から示すべきか。むむむ……
<2007-03-04追記> strengthを明示的に使ってはいないが、こんな感じか。
fmap swap (pure x ★ u) = {- definition of pure -} fmap swap (fmap (\_ -> x) unit ★ u) = fmap swap (fmap (\_ -> x) unit ★ fmap id u) = {- naturality of ★ -} fmap swap (fmap ((\_ -> x)×id) (unit ★ u)) = fmap ((\y -> (y,x)) . snd) (unit ★ u)) = {- left identity -} fmap (\y -> (y,x)) u = {- right identity -} fmap ((\y -> (y,x)) . fst) (u ★ unit) = fmap (id × (\_ -> x)) (u ★ unit) = {- naturality of ★ -} fmap id u ★ fmap (\_ -> x) unit = u ★ fmap (\_ -> x) unit = {- definition of pure -} u ★ pure x
</2007-03-04追記>
あと、「pure f <*> x1 <*> x2 <*> … <*> xn
」を「iI f x1 x2 … xn Ii
」と書けるようにする方法は Idiomatica.lhs に詳しい。しかし、こういうこと考えるやつは頭おかしいと思う……
教えてくん質問で恐縮ですが、strong monad ってどういうのを言うんでしょう?
一般に strong ??? というのは適当な条件(coherence condition)を満たす自然変換 τ_{X,Y}: X□TY→T(X□Y) が存在する ??? のことで、モナドの場合には λ_A: 1□A→A, α_{A,B,C}: (A□B)□C→A□(B□C) を自然変換として以下の条件になります。<br><br>(1) T λ_A ・ τ_{1,A} = λ_TA<br>(2) T α_{A,B,C} ・τ_{A□B,C} = τ_{A,B□C} ・ (id_A □ τ_{B,C}) ・ α_{A,B,TC}<br>(3) τ_{A,B} ・ (id_A □ η_B) = η_{A□B}<br>(4) τ_{A,B} ・ (id_A □ μ_B) = μ_{A□B} ・ T τ_{A,B} ・ τ_{A,TB}<br><br>また、Haskellでは<br> t :: Monad m => (a, m b) -> m (a, b)<br> t (a,m) = m >>= \b -> return (a,b)<br>と定義することにより、Monadクラスのインスタンスは全て strong monad になります。
丁寧な回答ありがとうです。ぐは、むずいー。<br>strong monoidal functor というのが Mac Lane の本に載ってますけど、あれも strong ??? の一種だと思っていいんですかね、そうすると。
> 丁寧な回答ありがとうです。ぐは、むずいー。<br><br>条件の細部はあまり気にする必要ないと思います。<br>結局のところ、τが既存の他の操作と整合的であることを言っているだけなので。<br><br>> strong monoidal functor というのが Mac Lane の本に載ってますけど、あれも strong ??? の一種だと思っていいんですかね、そうすると。<br><br>↓のやつですね。<br><br>| F_0: e'→F(e)<br>| F_2(a,b): F(a)□F(b)→F(a□b)<br>| ……<br>| A monoidal functor is said to be ((*strong*)) when F_0 and all the F_2(a,b) are isomorphisms.<br><br>これは違うと思います。<br>やっぱり「一般に strong ??? というのは〜」というのは一般化しすぎでした……(汗<br># ちなみに、τは tensorial strength と呼ばれるのですが、他にも functorial strength とかもあったりします。