[英]Type Lambda on context bound and the role of type alias
我必须为 Ordering[Option[T]] 编写一个上下文绑定
事实证明,解决方案是
def test[T: ({type L[x] = Ordering[Option[x]]})#L](value1: Option[T], value2: Option[T]) = {
val e = implicitly(Ordering[Option[T]].compare(value1, value2))
}
所以稍微玩了一下 lambda 类型以更好地理解,导致我编写了没有类型 lambda 的版本:
type L[x] = Ordering[Option[x]]
def testN[T: L](value1: Option[T], value2: Option[T]) = {
implicitly[L[T]].compare(value1, value2)
}
使用类型 lambda 的许多示例是具有 2 个参数的类型构造函数,例如 MAP[K,V]。
在这种情况下,我们没有这个问题。
所以我只是想知道,为什么不拥有这样的东西
def test[T: Ordering[Option]](value1: Option[T], value2: Option[T]) = {
val e = implicitly(Ordering[Option[T]].compare(value1, value2))
}
显然它不起作用。 我想我理解了所有要点,没有定义类型构造函数Ordering[Option[_]]
。
我们订购的是:
trait OptionOrdering[T] extends Ordering[Option[T]] {
def optionOrdering: Ordering[T]
def compare(x: Option[T], y: Option[T]) = (x, y) match {
case (None, None) => 0
case (None, _) => -1
case (_, None) => 1
case (Some(x), Some(y)) => optionOrdering.compare(x, y)
}
}
implicit def Option[T](implicit ord: Ordering[T]): Ordering[Option[T]] =
new OptionOrdering[T] { val optionOrdering = ord }
因为它代表Ordering[Option[T]]
在上面的定义中,是Ordering[Option[T]] forSome {type T}
阿卡生存,因此一个适当的类型,而不是一个类型构造函数。
所以如果我是正确的,我们在这里做什么:
({type L[x] = Ordering[Option[x]]})#L
或在这里:
type L[x] = Ordering[Option[x]]
正在定义类型构造函数Ordering[Option[_]]
。
问题 1:
1 - 我的理解正确吗? 这就是类型 Lambda 在这里所做的吗?
2 - 我在这里有点困惑,所以类型别名允许您从其他类型构造函数的组合中创建类型构造函数。 从某种意义上说,我试图理解类型别名与类型变量的正式作用。
scala> type e0 = Ordering[Option[_]]
defined type alias e0
scala> :kind -v e0
e0's kind is A
*
This is a proper type.
scala> type e1[w] = Ordering[Option[w]]
defined type alias e1
scala> :kind -v e1
e1's kind is F[A]
* -> *
This is a type constructor: a 1st-order-kinded type.
scala>
匿名类型构造函数
({type L[x] = Ordering[Option[x]]})#L
是命名类型构造函数
type L[x] = Ordering[Option[x]]
什么匿名(值)构造函数
(x: Int) => x + 1
是命名(值)构造函数
val f = (x: Int) => x + 1
例如
scala> lazy val v: (({type L[x] = Ordering[Option[x]]})#L)[Int] = ???
lazy val v: scala.math.Ordering[Option[Int]] // unevaluated
scala> lazy val v: L[Int] = ???
lazy val v: L[Int] // unevaluated
scala> lazy val v = ((x: Int) => x + 1)(41)
lazy val v: Int // unevaluated
scala> lazy val v = f(41)
lazy val v: Int // unevaluated
在 Scala 3 (Dotty) 中,您将能够替换“暴行”
无论如何,对 dotty 中的 kind 投影仪的需求较少,因为我们有原生类型的 lambdas 而不是涉及结构类型的暴行。
使用漂亮的类型 lambda 语法
Starting dotty REPL...
scala> lazy val v: (({type L[x] = Ordering[Option[x]]})#L)[Int] = ???
lazy val v: Ordering[Option[Int]]
scala> lazy val v: ([x] =>> Ordering[Option[x]])[Int] = ???
lazy val v: Ordering[Option[Int]]
上下文绑定语法
def test[T: ({type L[x] = Ordering[Option[x]]})#L](value1: Option[T], value2: Option[T]) = ???
相当于
def test[T](value1: Option[T], value2: Option[T])(implicit ev: (({type L[x] = Ordering[Option[x]]})#L)[T]) = ???
这简化为
def test[T](value1: Option[T], value2: Option[T])(implicit ev: Ordering[Option[T]]) = ???
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.