鉴于我有一个现有的ADT,是否可以创建一个通用的monoid。
从现在开始,我在ADT中拥有尽可能多的monoid,但它不是DRY。
以下是代码:
import scalaz._
import Scalaz._
object DataRework extends App {
sealed trait MultiItemValue {
type MV
def value: Seq[MV]
}
case class StringValue(value: Seq[String]) extends MultiItemValue{type MV = String}
case class BooleanValue(value: Seq[Boolean]) extends MultiItemValue{type MV = Boolean}
implicit object BooleanValueMonoid extends Monoid[BooleanValue] {
override def zero: BooleanValue = BooleanValue(Nil)
override def append(f1: BooleanValue, f2: => BooleanValue): BooleanValue = BooleanValue(f1.value ++ f2.value)
}
implicit object StringValueMonoid extends Monoid[StringValue] {
override def zero: StringValue = StringValue(Nil)
override def append(f1: StringValue, f2: => StringValue): StringValue = StringValue(f1.value ++ f2.value)
}
我想要类似的东西,但我发现这段代码因为重复而变得丑陋:
implicit object GenericMonoid extends Monoid[MultiItemValue] {
override def zero: MultiItemValue = ???
override def append(f1: MultiItemValue, f2: => MultiItemValue): MultiItemValue = (f1, f2) match {
case (sv1: StringValue, sv2: StringValue) => StringValue(sv1.value ++ sv2.value)
case (bv1: BooleanValue, bv2: BooleanValue) => BooleanValue(bv1.value ++ bv2.value)
}
}