セミグループの目的は、結合性と閉鎖性を確実にすることです。モノイドの目的は、セミグループに基づいており、追加のアイデンティティを提供します。|+| を使用する場合 semigroup アペンダー、暗黙のセミグループではなく暗黙のモノイドを定義した理由
初期値を必要としないreduceLeftを使用しているコードは次のとおりです
val result1 = List(Staff("John", 36), Staff("Andrew", 30))
val result2 = List(Staff("John", 40), Staff("Danny", 30))
val result3 = List(Staff("Andrew", 30))
val result4: List[Staff] = List()
implicit val staffListSemigroup = new Monoid[List[Staff]] {
override def zero: List[Staff] = Nil
override def append(f1: List[Staff], f2: => List[Staff]): List[Staff] = {
val mapSemigroup = f1.map(t => (t.name, t.numberOfTasks)).toMap |+| f2.map(t => (t.name, t.numberOfTasks)).toMap
mapSemigroup.map(t => Staff(t._1, t._2)).toList
}
}
val result = List(result1, result2, result3, result4).reduceLeft(_ |+| _)
assert(result.size == 3)
staffListSemigroup が Semigroup[List[Staff]] の場合、コンパイル エラーは値 |+| です。List[SemigroupSpec.this.Staff] のメンバーではありません
また、|+| の定義は 半群の中にあります
final class SemigroupOps[F] private[syntax](val self: F)(implicit val F: Semigroup[F]) extends Ops[F] {
////
final def |+|(other: => F): F = F.append(self, other)
final def mappend(other: => F): F = F.append(self, other)
final def ⊹(other: => F): F = F.append(self, other)
////
}
よろしくお願いします
編集
@Travisの回答が続きますが、それが正しいとは思いません。暗黙的な値の場合、特定の値は常に一般的な値をオーバーライドします。ここに私が書いたコード例があります:
case class Foo(i : Int, s : String)
class Test[T] {
def print = "print test"
}
implicit val test = new Test[Any]
implicit val testMoreSpecific = new Test[Foo] {
override def print = "print Foo"
}
def doStuff[A](implicit test: Test[A]) = {
test.print
}
doStuff[Foo] //it successfully print out print Foo
doStuff //compilation error, ambiguous implicit value found
それは、Scalaz では Foo のようなメソッドで指定された型が指定されていないためでしょうか。