加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

斯卡拉:订购逆转

发布时间:2020-12-16 08:54:34 所属栏目:安全 来源:网络整理
导读:有什么理由说 Scala的Ordering特性不是逆变的吗?一个激励性的例子如下. 假设我想执行有序插入.我可能有签名功能 def insert[A,B : A](list: List[A],item: A)(implicit ord: Ordering[B]): List[A] 在这里,我有一个接受超类型A的Ordering.我想这在你处理cas
有什么理由说 Scala的Ordering特性不是逆变的吗?一个激励性的例子如下.

假设我想执行有序插入.我可能有签名功能

def insert[A,B >: A](list: List[A],item: A)(implicit ord: Ordering[B]): List[A]

在这里,我有一个接受超类型A的Ordering.我想这在你处理case类时很有用.例如:

abstract class CodeTree
case class Fork(left: CodeTree,right: CodeTree,chars: List[Char],weight: Int) extends CodeTree
case class Leaf(char: Char,weight: Int) extends CodeTree

def weight(tree: CodeTree): Int 
def chars(tree: CodeTree): List[Char] 

implicit object CodeTreeOrdering extends Ordering[CodeTree] {
  def compare(a: CodeTree,b: CodeTree): Int = weight(a) compare weight(b)
}

我希望我的插入函数可以使用类型List [CodeTree],List [Leaf]或List [Fork].但是,由于Ordering不是逆变的,我需要为每个案例定义隐式排序.

如果我定义

trait MyOrdering[-A] {
  def compare(a: A,b: A): Int
}

一切都按预期工作.

有没有其他方法可以实现我的目标?

编辑:

我目前的解决方案是将insert定义为

def insert[A](list: List[A],item: A)(implicit ord: Ordering[A]): List[A]

在处理List [CodeTree]时工作正常.我也定义了(灵感来自scalaz库):

trait Contravariant[F[_]] {
  def contramap[A,B](r: F[A],f: B => A): F[B]
}

implicit object OrderingContravariant extends Contravariant[Ordering] {
  def contramap[A,B](r: Ordering[A],f: B => A) = r.on(f)
}

implicit def orderingCodeTree[A <: CodeTree]: Ordering[A] =
  implicitly[Contravariant[Ordering]].contramap(CodeTreeOrdering,identity)

我正在为Ordering [A<:CodeTree]实例定义隐式工厂函数.

解决方法

从上面评论中链接的“scala-language”线索中汲取了更多详细的答案.

Ordering不是逆变的原因是,这与隐式解决中使用的特异性概念不合理.隐式解析将尝试为参数选择最“特定”的类型,并且如果它是其子类型,则认为一种类型比另一种更具体.这在协变情况下是有意义的:我宁愿对我的字符串列表具有隐式特定,而不是任何旧列表.然而,在逆变情况下,它想要选择错误的东西:

trait Ord[-A]
A <: B
Ord[B] <: Ord[A]

因此,它会选择“最具体”的排序,如果有的话,订购[Any].

看起来有一个big discussion正在改变关于scala语言组的逆变参数定义’特异性’的方式.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读