2011年12月8日木曜日

Bind

昨日は rpscala へ行ってきました。
直接感想等をもらえてうれしかったです。
いつも御世話になっている皆さんに少しでも役に立つようがんばります。

Bind

今日はBindです。
Bindは型Z[_]を型パラメータにとり、型Z[A]と関数A => Z[B]を受け取り、Z[B]を返す関数bindを持ちます。
Haskellでは>>=にあたります。


この例ではScalaChanFunctorとScalaChanBindを定義し、 MAに定義されたmap,flatMapが使えるようになったかを確認しました。

flatMap, >>=, >>=|, >|>

flatMapと>>=は同じ関数です。
>>=|と>|>も同じ関数です。
>>=|, >|> はflatMap, >>=と違い、内包していた値を捨て、値だけを渡します。


ちなみにflatMap, >>=の糖衣関数∗、>>=|, >|>の糖衣関数∗|が定義されています。

forever

使い方がよく分からない関数。
>|> を使い、foreverの結果を連結し続けます。
なので評価するとStackOverflowError必至だと思うのですが・・・


join

型M[A]のAに、M[A]が適用されたM[M[A]]を連結し、M[A]を返します。
要は汎用的flatten。
糖衣関数にμがあります。


最後の例はjoinを行ったことにより、

(\a. (\b. a + b))




(\a. (\b. b)(a) + a)

に変換されました。

値を適用すると、

(\a. (\b. a + b))(5)(5) ->
(\b. 5 + b)(5) ->
5 + 5 -> 10

(\a. (\b. b)(a) + a)(5)
(\b. b)(5) + 5
5 + 5 -> 10

となり、関数に値を2度適用する関数であることが分かります。

Bindはbindという1つの関数だけを持っていますが、それを定義するだけでこれだけのものが使えるようになります。

Scalazおそるべし・・・・!



※追記

joinのところの訂正

読み直したらとても違和感を感じたので、定義を読み直したら全然違ったという・・・

Predefの<:<が恒等関数のようなものを返すことは分かっていたのですが・・・・・

実際はこうなります。

(\r. (\f. (\t f(r(t))(t)))(\i. (\j. i + j)))(\x. x)(5)
(\f. (\t f((\x. x)(t))(t)))(\i. (\j. i + j))(5)
(\t (\i. (\j. i + j))((\x. x)(t))(t))(5)
(\i. (\j. i + j))((\x. x)(5))(5)
(\i. (\j. i + j))(5)(5)
(\j. 5 + j)(5)
5 + 5
10

0 件のコメント:

コメントを投稿