よくわかりません

2006 | 10 |
2007 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 12 |
2008 | 02 | 07 | 10 |
2009 | 01 | 02 | 03 | 04 | 05 | 08 |
カテゴリー
 | 

2007-05-31

[] MonadとArrowの関係。

昨日のArrowのエントリ

MonadもArrow(に出来る)…みたいだけど詳しい事は書いてなかった。

と書いたけど、手っ取り早く、GHC6.6.1のControl.Arrowのソースを見てみた。


要は、モナド自体じゃなくて、モナドの>>=の右辺に渡す b -> m c *1関数の方をArrowにしてしまう、という話だ。


newtype Kleisli m b c = Kleisli { runKleisli :: b -> m c }

instance Monad m => Arrow (Kleisli m) where
	arr f = Kleisli (return . f)
	Kleisli f >>> Kleisli g = Kleisli (\b -> f b >>= g)
	first (Kleisli f) = Kleisli (\ ~(b,d) -> f b >>= \c -> return (c,d))

ただしArrowのカタチの「a b c」に揃えるために、>>= の右辺に渡す b -> m c な関数を、容れ物(Kleisli)に入れる。入れると

Kleisli m b c 

こういうカタチに。「Kleisli m」がArrowの種類の型a、「b」が"引数"の型b、「c」が"返値"の型c。モナドの種類m毎に、Kleisli mなるArrowの種類が出来る。


で、メソッド実装定義を見てみると、

Arrowのからくりである (>>>) と first(並列結合(***)はこれで作れる) の中に、モナドのからくりである (>>=) が仕込まれている。


これによって、 (>>>) が、モナドを (>>=) で繋ぐ役割を果たす。つまり、aをfしてgしてhする

(return a) >>= f >>= g >>= h

が、

runKleisli (arr f >>> Kleisli g >>> Kleisli h) a

になる。


あと、ArrowにはArrowPlus(とArrowZero)ってのがあって、

class Arrow a => ArrowZero a where
	zeroArrow :: a b c
class ArrowZero a => ArrowPlus a where
	(<+>) :: a b c -> a b c -> a b c

やはり、MonadPlusが対応する、と。

instance MonadPlus m => ArrowZero (Kleisli m) where
	zeroArrow = Kleisli (\x -> mzero)
instance MonadPlus m => ArrowPlus (Kleisli m) where
	Kleisli f <+> Kleisli g = Kleisli (\x -> f x `mplus` g x)


誤りなど、乞うご指摘。

*1:普通は a -> m b って書くけど、Arrowのa b cと合わせるため こう書いておく

スパム対策のためのダミーです。もし見えても何も入力しないでください
ゲスト


画像認証

 | 
最近のコメント
最近のトラックバック
ASUS Eee PC S101 EEEPCS101-BLACK (GRAPHITE) グラファイト EEEPCS101-BLK011X起動バカ速。 PFU Happy Hacking Keyboard Professional JP 墨 PD-KB420B一般社会では結局JIS。 NANAO FlexScan 20.1インチ 液晶ディスプレー  ブラック S2031W-HBK安くて縦横自在でナナオ。 後傾姿勢作業の楽さは異常。
プロフィール

r-west

r-west はてなダイアリープラス利用中

ぷろぐらまーわなびー。よくわからないまま書いてるメモ。オリジナルのコードはデフォでNYSLです。