そしてどんどん難しくなっていくScalazネタ。
実際危ない!
Apply
Applyは名の通り適用のための型クラスです。
しかし、ただ関数に値を適用するものではなく、コンテナ内の関数にコンテナ内の値を適用します。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) |
FunctorBindApplyはApplysに定義されています。
FunctorとBindを暗黙的にとり、Applyを返します。
<*>, <**>, <***>, <****>, <*****>
Functorではmap、Bindでは>>=と代表する関数がありますが、Applyでは<*>です。
これは<*>の場合は先程の例の通りですが、<**>からはコンテナと関数、implicit parameterにFunctorをとります。
*が増えるごとに、コンテナの数、関数の引数が増えていきます。
ただし、値がNilやNone, Leftなどが含まれている場合はその値が返ります。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
"Scala".some <*> ((_: String) |+| "ちゃんかわいい").some assert_=== "Scalaちゃんかわいい".some | |
("Scala".some <**> none)(_ |+| _) assert_=== none | |
(3.right[String] <***> ("4".left, 6.right))(_ |+| _ |+| _) assert_=== "4".left |
<|*|>, <|**|>, <|***|>, <|****|>
コンテナをわたし、コンテナに包まれたタプルを返します。
ただし、値がNilやNone, Leftなどが含まれている場合はその値が返ります。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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] |
*>, <*
>, <が指す値を返します。
ただし、値がNilやNone, Leftなどが含まれている場合はその値が返ります。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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] |
コピーアンドペースト重点。
これらの関数は型により動作が変わりますが、大体の型はこのような動きをします。
0 件のコメント:
コメントを投稿