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