あどけない話

Internet technologies

apの実装を読み解く

Applicativeスタイルの一般的な形は、以下のようになる。

f <$> m1 <*> m2 <*> m3 ...

<$> は liftM (あるいは fmap)の別名、ap は <*> の別名だと思ってよい。ap の実装を見てみると、以下のように定義してある。

ap :: (Monad m) => m (a -> b) -> m a -> m b
ap =  liftM2 id

最初、意味がまったく分からず、nobsun と一緒に考えた。その結果を忘れないように残しておく。

liftM2 のシグニチャと実装は以下の通り。この記事では型だけが重要である。

liftM2 :: (a -> b -> c) -> m a -> m b -> m c
liftM2 f m1 m2 = do
    x1 <- m1
    x2 <- m2
    return (f x1 x2)

id の型は以下の通り。

id :: a -> a

ここで、id の型を b -> c を

id :: (b -> c) -> (b -> c)

と考え、liftM2 に代入すると、LiftM2 の a も b -> c になる訳だから、次のようになる。

liftM2 id :: m (b -> c) -> m b -> m c

という訳で、ap の型が出てきた。

ちなみに、ap の別定義として、以下がある。

ap :: (Monad m) => m (a -> b) -> m a -> m b
ap =  liftM2 ($)

($) の型は以下の通り。

($) :: (a -> b) -> a -> b

これは、id の変形した型と同じだ。だから、この定義でもよいことが分かる。