2011年12月25日日曜日

Kleisli

Kleisliを忘れてました。

Kleisli

Kleisliはある入力をとり、出力をコンテナで包むものです。
Scalazの例でよく出てくる☆はこいつです。

lazy val f: Kleisli[Option, Int, String] = kleisli(5.shows +>: _.shows.some)
f(5) assert_=== Some("55")
lazy val g: Kleisli[Option, String, Int] = ☆(_.parseInt.toOption)
g("5") assert_=== Some(5)
view raw kleisli1.scala hosted with ❤ by GitHub

Kleisliの合成には、>=>と<=<があります。

(f >=> g).apply(5) assert_=== Some(55)
(f <=< g).apply("5") assert_=== Some("55")
(f <=< g).apply("Scalaz") assert_=== None
view raw kleisli2.scala hosted with ❤ by GitHub

Function1W#kleisliは結果をコンテナで包むKleisliをつくります。

lazy val h: Int => Int = _ |+| 2
h.kleisli[NonEmptyList].apply(5) assert_=== NonEmptyList(7)
view raw kleisli3.scala hosted with ❤ by GitHub

Kleislis#askはKleisliにおける恒等関数をつくります。

ask[NonEmptyList, Int].apply(5) assert_=== NonEmptyList(5)
(ask[Option, Int] >=> f).apply(5) assert_=== f(5)
view raw kleisli4.scala hosted with ❤ by GitHub

その他のメソッド

f =<< 0.some assert_=== Some("50")
f =<< none assert_=== None
h.kleisli[NonEmptyList].compose(_.list).apply(5) assert_=== List(7)
(h.kleisli[PartialApply1Of2[Validation, NumberFormatException]#Apply].compose(_.toOption) >=> f).apply(5) assert_=== Some("57")
f.traverse(nel(5, 5)) assert_=== Some(NonEmptyList("55", "55"))
g.traverse("Scalaz".wrapNel) assert_=== None
view raw kleisli5.scala hosted with ❤ by GitHub

  • =<<
    • コンテナの要素をKleisliに適用
  • compose
    •  出力のコンテナを変える。
  • traverse
    • 要素をコンテナで包む。

KleisliはA => M[B]の形の関数で、合成ができて、☆という印象。
scalaz.httpの資料で、routingにKleisliを使っています。
"scalaz http kleisli"でググるとでてきます。

0 件のコメント:

コメントを投稿