Reputation: 406
I have the following:
trait Grabber[A, B] {
def name: String
def grab(a: A): Option[B]
}
object Grabber {
implicit def toBooleanGrabber[A](s: String, f: A => Option[Boolean]) =
new BooleanGrabber[A] {
override val name: String = s
override def grab(a: A): Option[Boolean] = f(a)
}
implicit def toDoubleGrabber[A](s: String, f: A => Option[Double]) =
new DoubleGrabber[A] {
override val name: String = s
override def grab(a: A): Option[Double] = f(a)
}
implicit def toLongGrabber[A](s: String, f: A => Option[Long]) =
new LongGrabber[A] {
override val name: String = s
override def grab(a: A): Option[Long] = f(a)
}
def apply[A, B](
s: String,
f: A => Option[B]
)(implicit ev: (String, A => Option[B]) => Grabber[A, B]): Grabber[A, B] =
ev(s, f)
}
trait BooleanGrabber[A] extends Grabber[A, Boolean]
trait DoubleGrabber[A] extends Grabber[A, Double]
trait LongGrabber[A] extends Grabber[A, Long]
The apply
method works fine, but (per its explicit definition) it returns a Grabber[A, B]
. Is there a way to change the apply
method's signature (slightly, hopefully) to return the children of Grabber[A, B]
? For instance, the invocation that uses toBooleanGrabber
would ideally return a BooleanGrabber[T]
, rather than a Grabber[T, Boolean]
.
Upvotes: 0
Views: 283
Reputation: 15086
You can add an extra type parameter to your apply
method.
def apply[A, B, R](
s: String,
f: A => Option[B]
)(implicit ev: (String, A => Option[B]) => R with Grabber[A, B]): R =
ev(s, f)
Upvotes: 2