Определения для 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]);
}
List@#<^>
запускает предоставленную функцию из NonEmptyList[A] => B
, если сводный список не пуст, в противном случае возвращает Zero
для типа B
.MA#min
фактически возвращает Option[B]
- это общая функция для контейнеров, а не специфическая для NonEmptyList
, где она может возвращать B
.
Более прямой путь для достижения этой целипозвонить MA#min
напрямую.К сожалению, List
уже имеет функцию min
, новую в Scala 2.8, поэтому неявное представление 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 - это грубая форма пространства имен!
Примечание: вы можете упростить свой экземпляр Order
для CC
:
implicit val CCOrder: Order[CC] = orderBy(_.v)
CCOrder: scalaz.Order[CC] = scalaz.Orders$$anon$2@fc2528