避免在地图操作上显式类型参数

时间:2014-04-15 19:49:54

标签: scala functional-programming implicit scalaz

我有一个Span[A]数据类型,可以跟踪A类型的最小值和最大值。因此,我要求A拥有Scalaz Order实例。这是实现的样子:

trait Span[A] {
  val min: A
  val max: A
}
object Span {
  def apply[A : Order](id: A): Span[A] = new Span[A] {
    override val min = id
    override val max = id
  }
  def apply[A : Order](a: A, b: A): Span[A] = {
    val swap = implicitly[Order[A]].greaterThan(a, b)
    new Span[A] {
      override val min = if (swap) b else a
      override val max = if (swap) a else b
    }
  }
  implicit def orderSpanSemigroup[A : Order]: Semigroup[Span[A]] = new Semigroup[Span[A]] {
    override def append(f1: Span[A], f2: => Span[A]): Span[A] = {
      val ord = implicitly[Order[A]]
      Span(ord.min(f1.min, f2.min), ord.max(f1.max, f2.max))
    }
  }
}

apply方法似乎按预期工作,因为我可以这样做:

val a = Span(1) // or Span.apply(1)

如果我尝试使用仿函数映射此值,例如Option[Int]

,则会出现故障
val b = 1.some map Span.apply
// could not find implicit value for evidence parameter of type scalaz.Order[A]

但是,我可以使用显式类型参数来修复错误:

val c = 1.some map Span.apply[Int]

为什么会这样?有没有办法避免这种显式类型参数?我想知道它是否与this issue有关,因为我在尝试使用自己的隐式Order实例时遇到了问题。当然,它也在Int输入失败,所以它可能只是参数化方法的限制。

0 个答案:

没有答案