Implicit proofs from type within a tag
Let's say we have the following:
object MyValue {
case class MyBoolean(record: Boolean) extends MyValue
case class MyDouble(record: Double) extends MyValue
}
trait MyValue
and the sealed sign:
object MyValueGrabber {
trait MyBooleanGrabber[T] extends MyValueGrabber[T] {
override def apply(record: T): Option[MyValue.MyBoolean]
}
trait MyDoubleGrabber[T] extends MyValueGrabber[T] {
override def apply(record: T): Option[MyValue.MyDouble]
}
}
sealed trait MyValueGrabber[T] {
def apply(record: T): Option[MyValue]
}
and also a mapping between a type MyValue
and another type with which it is associated:
object Mapper {
implicit val myBooleanMapper = new Mapper[MyValueGrabber.MyBooleanGrabber[_], String] {
override def getValue: String = "found a bool"
}
implicit val myDoubleMapper = new Mapper[MyValueGrabber.MyDoubleGrabber[_], Long] {
override def getValue: Long = 100L
}
}
trait Mapper[A, B] {
def getValue: B
}
and then we have:
trait HolyGrail[T] {
def name: String
def myValueGrabber: MyValueGrabber[T]
def getValue[U] = ???
}
The question is, how do we implicitly use Mapper
to return the correct type U
. Ideally, it would be something like:
def getValue[U](implicit ev: Mapper[myValueGrabber.type, U]) = ev.getValue // doesn't work
source to share
You should use it like this:
def getValue[U](implicit ev: Mapper[MyValueGrabber[T], U]) = ev.getValue
How methods don't have .type
. (Their converted function is there, but I think this is not what you want.)
Based on the clarifications in the comments, I think you want something like Shapeless' HMap .
You may have to change your trait a little ValueGrabber
:
sealed trait MyValueGrabber[T, -R <: MyValue] {
def apply(record: T): Option[R]
}
or
sealed trait MyValueGrabber[T] {
type R <: MyValue
def apply(record: T): Option[R]
}
perhaps the latter is harder to use in your getValue
:
def getValue[U, O](implicit ev: Mapper[MyValueGrabber[T] {type R = O}, U]): U = ev.getValue
the first one would look like this (but not what you want as I understand it):
trait HolyGrail[T, R] {
def name: String
def myValueGrabber: MyValueGrabber[T, R]
def getValue[U](implicit ev: Mapper[MyValueGrabber[T, R], U]): U = ev.getValue
}
I dont know how to do what you want (path dependent type with trait) without formless.
source to share