scala - create Scalaz equal instance on class with subtypes -


i have following simple adt, how implement instance of equality typeclass without resorting explicitly pattern matching possible combinations?

import scalaz._ import scalaz._  sealed trait billinginfo case class creditcard(number: int, holder: string, address: string) extends billinginfo case object cod extends billinginfo case class invoice(cid: string) extends billinginfo  object billinginfo{    implicit val billingequal = equal.equal[billinginfo]{(b1,b2) =>     (b1,b2) match {       case (invoice(c1), invoice(c2)) => c1 === c2       case (creditcard(a,b,c), creditcard(d,e,f)) =>         === d &&         b === e &&         c === f //writing exhaustive match tedious     }   } 

you've got (at least) 2 options. 1 use "natural" equality. if don't have custom types case class members should work fine:

implicit val billingequal: equal[billinginfo] = equal.equala[billinginfo] 

or use shapeless's type class instance derivation:

import shapeless._ import scalaz.{ coproduct => _, :+: => _, _ }, scalaz._  object equalderivedorphans extends typeclasscompanion[equal] {   object typeclass extends typeclass[equal] {     def product[h, t <: hlist](eh: equal[h], et: equal[t]): equal[h :: t] =       tuple2equal(eh, et).contramap {         case h :: t => (h, t)       }      def project[a, b](b: => equal[b], ab: => b, ba: b => a): equal[a] =       b.contramap(ab)      def coproduct[l, r <: coproduct](       el: => equal[l],       er: => equal[r]     ): equal[l :+: r] = eitherequal(el, er).contramap {       case inl(l) => left(l)       case inr(r) => right(r)     }      val emptyproduct: equal[hnil] = equal.equal((_, _) => true)     val emptycoproduct: equal[cnil] = equal.equal((_, _) => true)   } }  import equalderivedorphans._ 

this derive equal instances case classes have equal instances members.

or of course enumerate cases, isn't terrible:

implicit val billingequal = equal.equal[billinginfo] {   case (invoice(c1), invoice(c2)) => c1 === c2   case (creditcard(a, b, c), creditcard(d, e, f)) =>     === d && b === e && c === f   case (cod, cod) => true   case _ => false } 

note don't need level of matching on tuple.


Comments

Popular posts from this blog

c++ - Difference between pre and post decrement in recursive function argument -

php - Nothing but 'run(); ' when browsing to my local project, how do I fix this? -

php - How can I echo out this array? -