ということでFunctorの紹介。
Functor
Pureと同じように型パラメータを1つとる型を型パラメータにとります。
fmapというコレクションでおなじみのmapと似た関数を持っています。
mapと違うところは要素を包む型が多相であるというところです。
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 Ikamusume[A](value: A) | |
implicit def IkamusumeEqual[A]: Equal[Ikamusume[A]] = equalA | |
implicit def IkamusumeShow[A]: Show[Ikamusume[A]] = showA | |
implicit def IkamusumeFunctor: Functor[Ikamusume] = new Functor[Ikamusume] { | |
def fmap[A, B](r: Ikamusume[A], f: A => B): Ikamusume[B] = Ikamusume(f(r.value)) | |
} | |
def mapAppend[M[_]: Functor, A: Semigroup](m: M[A], a: A) = m.map(_ |+| a) | |
mapAppend(List(1, 2, 4), 2) assert_=== List(3, 4, 6) | |
mapAppend(Ikamusume(100), 1) assert_=== Ikamusume(101) |
Identity
mapply
値を内包された関数に適用します。
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.mapply((1 |+| (_: Int)).some) assert_=== 2.some | |
List(1).mapply(List(1 +>: (_: List[Int]), (_: List[Int]) |+| List(1, 1))) assert_=== List(List(1, 1), List(1, 1, 1)) |
MA
map, map2, >|
mapは関数を渡し、内包する値に適用します。
map2はFunctorがネストしている場合に利用でき、ma.map(_.map(f))と等価です。
>| は値を渡し、その値で塗りつぶします。
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, 2).map(1 +) assert_=== (1, 3) | |
((_: Int) + 1).map(2 *).apply(5) assert_=== 12 | |
List(1.some, 2.some, 4.some).map2[Option, Int, Int](2 +) assert_=== List(3.some, 4.some, 6.some) | |
List(List(1, 2, 3), List(2, 2, 2)).map2[List, Int, Int](2 *) assert_=== List(2.replicate[List](3, _ |+| 2), 4.replicate[List](3)) | |
1.replicate[Stream](5) >| 3 assert_=== 3.replicate[Stream](5) |
fpair, fpure
fpairは内包された値のペアを作ります。
fpureは内包された値を指定した型で包みます。
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.fpair assert_=== Some((1, 1)) | |
List(1, 2, 3).fpair assert_=== List((1,1), (2,2), (3,3)) | |
1.some.fpure[List] assert_=== Some(List(1)) | |
List(1, 2, 3).fpure[Option] assert_=== List(Some(1), Some(2), Some(3)) |
comp
Option[List[Int]]をMA[M[_], A]とみなすとき、MにOptionが、AにList[Int]が適用されMA[Option, List[Int]]となります。
compではMにOption[List[_]]を、AにIntを適用したMA[({ type X[A] = Option[List[A]] })#X, Int]を返します。
MAの型としては型の部分適用されたものが返るので普通の型クラスは対応していません。
しかしCompをインポートすることでApplicativeとFunctorのimplicit valueを得ることができます。
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
import Comp._ | |
List.fill(2, 2)(1).comp.map(10 *) assert_=== List.fill(2, 2)(10) | |
List(1).some.comp.fpure[Option] assert_=== List(1.some).some | |
Ikamusume(100).some.comp.map(2 *) assert_=== Ikamusume(200).some |
InvariantFunctor
FunctorはInvatiantFunctorを継承しています。
MA
xmap
一度別の型に変換し、また元の型へ変換します。
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
("Hello" |+| "World")(Semigroup.IntSemigroup.xmap(_.shows)(_.size)) assert_=== "10" | |
(1 |+| 1)(Semigroup.StringSemigroup.xmap(_.toInt)(_.shows)) assert_=== 11 |
Semigroup以外に、Endo, Monoid, Memoのインスタンスが定義されています。
xmapはともかく、mapやmap2,compは使いどころが多いと思います。
積極的に使っていってコードをScalazで染め上げましょう!
0 件のコメント:
コメントを投稿