从类型为class

时间:2017-12-17 09:13:16

标签: scala

我有以下内容:

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]

apply方法工作正常,但(根据其显式定义)它返回Grabber[A, B]。有没有办法更改apply方法的签名(稍微有希望)以返回Grabber[A, B]的子项?例如,使用toBooleanGrabber的调用理想情况下会返回BooleanGrabber[T],而不是Grabber[T, Boolean]

1 个答案:

答案 0 :(得分:2)

您可以在apply方法中添加额外的类型参数。

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)