scala - Combinatorial explosion of implicit objects -
i have case class, this:
case class container[t, m](value: t, modifier: m) i want make possible have ordering on container t have ordering too. don't want make t <: ordered[t], because container should able contain non-orderable values well.
my first try implement ordered, this:
case class container[t, m](value: t, modifier: m) extends ordered[container[t, m]] { override def compare(that: container[t, m])(implicit ev: ordering[t]): int = ev.compare(value, that.value) } but doesn't work: because of implicit parameter, compare no longer implements trait.
so decided try type class approach:
class containerordering[t, m](implicit ev: ordering[t]) extends ordering[container[t, m]] { override def compare(x: container[t, m], y: container[t, m]): int = ev.compare(x.value, y.value) } implicit object containerorderingint extends containerordering[int, int] this works (if import ordering.implicits._), have new problem: every type m, need separate implicit object. there aren't many types want use in m position (in fact, derive sealed trait define elsewhere), still means combinatorial explosion of implicit objects need define. i'm ok having separate implicit object each t, m should orthogonal this.
there must better way this. maybe can leverage fact m extends sealed trait. however, haven't been able so. advice?
put ordering companion object!
object container { implicit def ordering[t: ordering, m] = new ordering[container[t, m]] { override def compare(x: container[t, m], y: container[t, m]): int = implicitly[ordering[t]].compare(x.value, y.value) } } now can use ordering using import container._ needed.
(ps: real trick of course make ordering implicit free defining every single ordering each possible type.)
Comments
Post a Comment