この記事は
Functional Ikamusume Advent Calendar jp 2011
と
一人Scalaz Advent Calendar
を兼ねているんじゃなイカ!?
Semigroup
Semigroupは結合可能という性質を表すでゲソ。
Semigroupは関数 def append(s1: S, s2: => S): S を持ち、2つの値から一つの結果を得る関数を持つでゲソ。
Semigroupのインスタンスはsemigroup関数を使うことで定義できるんじゃなイカ?
Semigroups#semigroup
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(syokusyu: Int = 10) | |
implicit def IkamusumeEqual: Equal[Ikamusume] = equalA | |
implicit def IkamusumeShow: Show[Ikamusume] = shows("ゲソ" * _.syokusyu) | |
implicit def IkamusumeSemigroup: Semigroup[Ikamusume] = semigroup(_.syokusyu + _.syokusyu |> Ikamusume) | |
(Ikamusume() |+| Ikamusume()).shows assert_=== "ゲソゲソゲソゲソゲソゲソゲソゲソゲソゲソゲソゲソゲソゲソゲソゲソゲソゲソゲソゲソ" |
Semigroupを利用する関数
|+|
加算だけでなく、型によって様々な動きをするでゲソ。
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 |+| 1 assert_=== 2 | |
List(1) |+| List(1) assert_=== List(1, 1) | |
"Hello" |+| "World" assert_=== "HelloWorld" | |
1.some |+| 1.some assert_=== 2.some | |
false |+| true assert_=== true | |
加算や連結、論理和のような動きをするでゲソ。
===と同様に型安全でもあるでゲソ!
・・・・・Semigroup単体だとこれだけでゲソ。
あまりにも寂しいのでZero, Monoidまでやろうじゃなイカ!
Zero
Zeroは単位元を表すでゲソ。
mzero
mzeroは型パラメータを取り、その型の単位元を返すでゲソ。
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
mzero[Int] assert_=== 0 | |
mzero[String] assert_=== "" | |
mzero[List[Int]] assert_=== nil[Int] | |
mzero[Option[Int]] assert_=== none[Int] |
matchOrZero
matchOrZeroは型パラメータとPartialFunctionを取り、マッチしない場合はその型の単位元を返すでゲソ!
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
lazy val geso: Option[Int] => String = _.matchOrZero { | |
case Some(n) => "ゲソ" * n | |
} | |
geso(2.some) assert_=== "ゲソゲソ" | |
geso(none) assert_=== "" |
Zeros#zero
Zeroのインスタンスはzeroにより定義できるんじゃなイカ?
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
implicit def IkamusumeZero: Zero[Ikamusume] = zero(Ikamusume(0)) | |
mzero[Ikamusume].shows assert_=== "" |
そして、SemigroupとZeroを兼ね備えたものがMonoidなのでゲソ!
Monoid
MonoidはSemigroupとZeroを継承したものでゲソ。
Monoidは
forall a. append(zero, a) == a
forall a. append(a, zero) == a
を満たすのでゲソ。
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
def check[A: Equal: Show: Monoid](a: A) = { | |
a |+| mzero[A] assert_=== a | |
mzero[A] |+| a assert_=== a | |
} | |
check(1) | |
check("Scalaz") | |
check(List(1, 2, 3)) | |
check(Ikamusume()) |
イカ娘も立派なモノイドじゃなイカ?
Monoid単体を利用する関数はほとんどないのでゲソ。
Monoidは他の型クラスと一緒に使うことが多いのでその時に紹介しようじゃなイカ!
0 件のコメント:
コメントを投稿