使用Scalaz.ListW键入推断问题。< ^>

时间:2010-07-28 09:56:05

标签: scala type-inference scalaz

我正在玩ListW.<^>,其定义如下:

def <^>[B: Zero](f: NonEmptyList[A] => B): B = value match {
  case Nil => ∅
  case h :: t => f(Scalaz.nel(h, t))
}

我无法弄清楚如何选择Option作为此示例的Zero类型

scala> case class CC(v : Int)
defined class CC

scala> val posns = List(CC(2), CC(5), CC(1))
posns: List[CC] = List(CC(2), CC(5), CC(1))

所以现在我有了这些东西的清单。我的目标是为Option[CC]的最小值/最大值取回posns,如果没有低于0的值且类似于最大值,则我得到None分钟。

scala> import scalaz._; import Scalaz._
import scalaz._
import Scalaz._

scala> implicit val CCOrder = new Order[CC] { 
       | def order(v1 : CC, v2 : CC) = orderBy( (v : CC) => v.v ).order(v1, v2) 
       | }
CCOrder: java.lang.Object with scalaz.Order[CC] = $anon$1@1e48d65

scala> posns.filter(_.v < 0) <^> (_.min)
res0: Option[CC] = None

scala> posns.filter(_.v > 0) <^> (_.max)
res1: Option[CC] = Some(CC(5))

选项完全我想要的Zero类型!任何人都可以解释如何通过typer选择Option吗?我没有声明任何地方

1 个答案:

答案 0 :(得分:5)

ListW#<^>MA#min的定义:

sealed trait MA[M[_], A] extends PimpedType[M[A]] {
  def min(implicit r: Foldable[M], ord: Order[A]): Option[A] =
    foldl1((x: A, y: A) => if (x ≨ y) x else y)
}

sealed trait ListW[A] extends PimpedType[List[A]] {
  def <^>[B: Zero](f: NonEmptyList[A] => B): B = value match {
    case Nil => ∅
    case h :: t => f(Scalaz.nel(h, t))
  }
}

以下是相关的推断类型,隐式转换和隐式参数。 scalac -Xprint:typer将揭示这一点。

object test {
  import scalaz._
  import Scalaz._

  case class CC(v: Int)
  val posns = List(CC(2), CC(5), CC(1))
  val filtered = posns.filter(((x$1: CC) => x$1.v.<(0)))
  val listw = Scalaz.ListTo[CC](posns.filter(((x$1: CC) => x$1.v.<(0))))
  listw.<^>[Option[CC]]{
    (x$2: scalaz.NonEmptyList[CC]) =>
      Scalaz.maImplicit[scalaz.NonEmptyList, CC](x$2).min(Foldable.NonEmptyListFoldable, CCOrder)
  }(Zero.OptionZero[CC]);
}
如果pimped列表非空,则

List@#<^>NonEmptyList[A] => B运行提供的函数,否则返回类型Zero的{​​{1}}。 B实际上会返回MA#min - 它是容器的常规函数​​,而不是Option[B]的特定函数,它可以返回NonEmptyList

更直接的方法是直接调用B。遗憾的是,MA#min已经有一个List函数,Scala 2.8中的新函数,因此如果没有类型提示,则不会触发min的隐式视图:

MA

这是在Scalaz中提供符号标识符的动机之一 - 它是命名空间的粗略形式!

附注:您可以简化posns.filter(_.v < 0).min <console>:16: error: could not find implicit value for parameter cmp: Ordering[CC] posns.filter(_.v < 0).min (posns.filter(_.v < 0): MA[List, CC]).min res7: Option[CC] = None 的{​​{1}}实例的实例:

Order