各コンビネータに対応する関数

type Combinator Prelude Monad Applicative
a -> a I x = x id ask
a -> b -> a K x y = x const return pure
(a -> b) -> (c -> a) -> c -> b B x y z = x (y z) (.) liftM
(a -> b -> c) -> b -> a -> c C x y z = x z y flip
(a -> a) -> a Y x = x (Y x) fix
(a -> b -> c) -> (a -> b) -> a -> c S x y z = x z (y z) ?? ap <*>

Sコンビネータの型は(a -> b -> c) -> (a -> b) -> a -> c
これで調べると、Readerモナドのap、Applicativeの<*>等が対応するようだ。

あまり深く考えずに Reader a を a -> と読み替えると、関数の型は以下のようになります。

関数 等価な関数
ap (a->b->c) -> (a->b) -> a -> c <*>

つまり Reader モナドは引数隠蔽モナドだと思えばいいわけですね。本当は第一引数があるのだけれども、あたかもそれが引数に存在しないかのように記述できると。

http://d.hatena.ne.jp/rst76/20091006/1254835633

*1 -> (a -> b) -> (a -> c)
というわけで,これが S コンビネータ
あと、Monadインスタンスである(Reader r)に対応する(>>=)が CSかも。

http://practical-scheme.net/chaton/haskell-ja/a/2009/11/02

Applicativeについて

どうやらMonadやArrowのようなフレームワーク(?)の一種らしい

Applicativeの使い方が少し見えてきました。
mapでこうやることが:
map (+ 1) [1, 2, 3] = [2, 3, 4]
Applicativeだとこうできる:
pure (+1) <*> [1, 2, 3] = [2, 3, 4]
いくつのリストを対象に関数を適用するかで、map = 1, zipWith = 2, zipWith3 = 3,...と使う関数を変えていかなくてはならないのですが、Applicativeであれば、pureと<*>だけで何個リストがあっても大丈夫...これはきれいです。

http://d.hatena.ne.jp/Otter_O/20080301/1204363038

そもそも、PreludeとControl.MonadとControl.ArrowとControl.Applicativeはそれぞれ導入の時期もずれていて、十分に整理されているわけではありません。

http://practical-scheme.net/chaton/haskell-ja/a/2009/10/30

追記
次のエントリーに求めていたものズバリがあった。

Sコンビネータいろいろ
モナドコンビネータ論理のコラボ!とか喜んでたら、既に先達が。

http://d.hatena.ne.jp/rst76/20091006/1254840491

PreludeにSかWを入れる提案があったが却下されてたらしい。

Joe Fasel argued for the inclusion of S or W in the prelude
on the grounds that a complete combinator base would be "neat".
But the majority of the Haskell committee didn't buy that.

http://www.haskell.org/pipermail/haskell-cafe/2005-February/009117.html

*1:->) a) がApplicativeクラスのインスタンスなので,この場合メソッド<*>の型は <*> :: ((->) a (b -> c) -> ((->) a b) -> ((->) a c) すなわち <*> :: (a -> (b -> c