1

Given I have an existing ADT, is it possible to create a generic monoid.

From now, I have as many monoid as classes in my ADT, but it's not DRY.

Here is the code :

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)
  }

I would like something like, but i found this code ugly due to some repetition :

  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)
    }
  }
Yann Moisan
  • 8,161
  • 8
  • 47
  • 91
  • I don't think so. How would you construct a `Monoid` for `Either[A,B]`, even if you have `Monoid[A]` and `Monoid[B]`? – ziggystar Jun 19 '15 at 07:58
  • I just want a `Monoid` for `MultiItemValue` – Yann Moisan Jun 19 '15 at 08:13
  • Yes, but it's also a sum type, just like `Either`. – ziggystar Jun 19 '15 at 08:48
  • I don't know how exactly this can be done, but pretty sure that the most achievable way you can do this is using the latest stuff from [shapeless](https://github.com/milessabin/shapeless). For inspiration you may start with [Ensime](https://github.com/ensime/ensime-server/blob/master/jerk/src/main/scala/org/ensime/jerk/JerkFormats.scala), if i'm not mistaken they are doing pretty much the same thing to auto-generate spray json typeclass instances on the fly. – 4lex1v Jun 19 '15 at 08:53

0 Answers0