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

前端之家收集整理的这篇文章主要介绍了使用Scalaz.ListW.<^>键入推断问题前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我正在玩 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(1))

所以现在我有了这些东西的清单.我的目标是为posns的最小值/最大值返回一个Option [CC],如果没有低于零的值且类似于max,则我得到min为min.

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选择的?我没有在任何地方宣布它!

解决方法

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(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]);
}

列表@#< ^>从NonEmptyList [A] =>运行提供的函数B如果pimped列表非空,否则返回类型B的Zero .MA#min实际返回Option [B] – 它是容器的通用函数,而不是NonEmptyList的特定函数,它可以返回B .

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

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

这是在Scalaz中提供符号标识符的激励原因之一 – 它是命名空间的粗略形式!

附注:您可以简化CC的Order实例的实例:

implicit val CCOrder: Order[CC] = orderBy(_.v)
CCOrder: scalaz.Order[CC] = scalaz.Orders$$anon$2@fc2528
原文链接:https://www.f2er.com/scala/827920.html

猜你在找的Scala相关文章