2011年12月11日日曜日

Apply

一昨日の分書いてない、昨日の分書いてない、今日の分書いてない・・・・・
そしてどんどん難しくなっていくScalazネタ。
実際危ない!

Apply

Applyは名の通り適用のための型クラスです。
しかし、ただ関数に値を適用するものではなく、コンテナ内の関数にコンテナ内の値を適用します。

case class ScalaChan[A](value: A)
implicit def ScalaChanEqual[A]: Equal[ScalaChan[A]] = equalA
implicit def ScalaChanShow[A]: Show[ScalaChan[A]] = showA
implicit lazy val ScalaChanFunctor: Functor[ScalaChan] = new Functor[ScalaChan] {
def fmap[A, B](a: ScalaChan[A], f: A => B): ScalaChan[B] = ScalaChan(f(a.value))
}
implicit lazy val ScalaChanBind: Bind[ScalaChan] = new Bind[ScalaChan] {
def bind[A, B](a: ScalaChan[A], f: A => ScalaChan[B]): ScalaChan[B] = f(a.value)
}
implicit lazy val ScalaChanApply: Apply[ScalaChan] = FunctorBindApply
ScalaChan(100) <*> ScalaChan((_: Int) + 100) assert_=== ScalaChan(200)
view raw apply1.scala hosted with ❤ by GitHub

FunctorBindApplyはApplysに定義されています。
FunctorとBindを暗黙的にとり、Applyを返します。

<*>, <**>, <***>, <****>, <*****>

Functorではmap、Bindでは>>=と代表する関数がありますが、Applyでは<*>です。
これは<*>の場合は先程の例の通りですが、<**>からはコンテナと関数、implicit parameterにFunctorをとります。
*が増えるごとに、コンテナの数、関数の引数が増えていきます。
ただし、値がNilやNone, Leftなどが含まれている場合はその値が返ります。

"Scala".some <*> ((_: String) |+| "ちゃんかわいい").some assert_=== "Scalaちゃんかわいい".some
("Scala".some <**> none)(_ |+| _) assert_=== none
(3.right[String] <***> ("4".left, 6.right))(_ |+| _ |+| _) assert_=== "4".left
view raw apply2.scala hosted with ❤ by GitHub

<|*|>, <|**|>, <|***|>, <|****|>

コンテナをわたし、コンテナに包まれたタプルを返します。
ただし、値がNilやNone, Leftなどが含まれている場合はその値が返ります。

List("Scalaちゃん") <|*|> List("イカ娘") assert_=== List(("Scalaちゃん", "イカ娘"))
List("Scala") <|**|> (nil[String], List("Scalaz")) assert_=== nil
'a'.right[Int] <|***|> ('b'.right[Int], 'c'.right[Int], 'd'.right[Int]) assert_=== ('a', 'b', 'c', 'd').right[Int]
view raw apply3.scala hosted with ❤ by GitHub

*>, <*

>, <が指す値を返します。
ただし、値がNilやNone, Leftなどが含まれている場合はその値が返ります。

1.some <* 10.some assert_=== 1.some
none[Int] *> 10.some assert_=== none
1.right[String] *> 10.right[String] assert_=== 10.right[String]
1.right[String] <* "10".left[Int] assert_=== "10".left[Int]
view raw apply4.scala hosted with ❤ by GitHub

コピーアンドペースト重点。

これらの関数は型により動作が変わりますが、大体の型はこのような動きをします。

0 件のコメント:

コメントを投稿