Scala 命令隐式转换?
Scala order implicit conversions?
我在 scala 顺序隐式中遇到了一些问题,有人可以帮助我吗?
下面是一些类的定义,我想做的是通过'popularity'.
比较Leaf和Node
class Tree
case class EmptyTree() extends Tree
case class Leaf(label: String, popularity: Double) extends Tree
case class Node(popularity: Double, left: Tree, right: Tree) extends Tree
例如:
val a = Leaf("a",10)
val b = Leaf("b",20)
val c = Node(30,a,b)
如果我们想通过 a 和 b 的受欢迎程度来比较它,通过添加隐式转换很容易做到,就像这样:
implicit val leavesOrder = new Ordering[Leaf] {
override def compare(x: Leaf, y: Leaf) =
implicitly[Ordering[Double]].compare(x.popularity, y.popularity)
}
但是如果我想通过 a 和 c 的受欢迎程度来比较它,我对此感到困惑,不知道如何添加隐式转换?
有人可以帮助我吗?
如果要比较 Leaf
和 Node
,可以为 Tree
创建隐式 Ordering
。
这里有一些(不完整的)代码,说明如何做到这一点:
implicit val treeOrder = new Ordering[Tree] {
override def compare(x: Tree, y: Tree) = (x,y) match {
case (Leaf(_,xP), Leaf(_,yP)) => xP compare yP
case (Node(xP,_,_), Leaf(_,yP)) => xP compare yP
case (Node(xP,_,_), Node(yP,_,_)) => xP compare yP
case (EmptyTree(), _) => -1
/* Add the rest of the cases here */
}
}
将 Tree
更改为 sealed trait
的奖励积分,以便编译器可以在您的模式匹配不完整时告诉您:)
我就是这样做的。将 Tree
class 更改为 sealed trait
这意味着模式匹配是详尽无遗的,因此编译器可以告诉您是否遗漏了什么。然后,您需要匹配 Tree 可以是的每种类型。并不是所有的人都有人气。
sealed trait Tree
case object EmptyTree extends Tree
case class Leaf(label: String, popularity: Double) extends Tree
case class Node(popularity: Double, left: Tree, right: Tree) extends Tree
implicit val treeOrdering = new Ordering[Tree] {
private val doubleOrdering = implicitly[Ordering[Double]]
def compare(a: Tree, b: Tree): Int = {
(a, b) match {
case (Node(p1, _, _), Node(p2, _, _)) => doubleOrdering.compare(p1, p2)
case (Leaf(_, p1), Node(p2, _, _)) => doubleOrdering.compare(p1, p2)
case (Node(p1, _, _), Leaf(_, p2)) => doubleOrdering.compare(p1, p2)
case (Leaf(_, p1), Leaf(_, p2)) => doubleOrdering.compare(p1, p2)
case (EmptyTree, _) => -1
case (_, EmptyTree) => 1
}
}
}
我在 scala 顺序隐式中遇到了一些问题,有人可以帮助我吗?
下面是一些类的定义,我想做的是通过'popularity'.
比较Leaf和Nodeclass Tree
case class EmptyTree() extends Tree
case class Leaf(label: String, popularity: Double) extends Tree
case class Node(popularity: Double, left: Tree, right: Tree) extends Tree
例如:
val a = Leaf("a",10)
val b = Leaf("b",20)
val c = Node(30,a,b)
如果我们想通过 a 和 b 的受欢迎程度来比较它,通过添加隐式转换很容易做到,就像这样:
implicit val leavesOrder = new Ordering[Leaf] {
override def compare(x: Leaf, y: Leaf) =
implicitly[Ordering[Double]].compare(x.popularity, y.popularity)
}
但是如果我想通过 a 和 c 的受欢迎程度来比较它,我对此感到困惑,不知道如何添加隐式转换?
有人可以帮助我吗?
如果要比较 Leaf
和 Node
,可以为 Tree
创建隐式 Ordering
。
这里有一些(不完整的)代码,说明如何做到这一点:
implicit val treeOrder = new Ordering[Tree] {
override def compare(x: Tree, y: Tree) = (x,y) match {
case (Leaf(_,xP), Leaf(_,yP)) => xP compare yP
case (Node(xP,_,_), Leaf(_,yP)) => xP compare yP
case (Node(xP,_,_), Node(yP,_,_)) => xP compare yP
case (EmptyTree(), _) => -1
/* Add the rest of the cases here */
}
}
将 Tree
更改为 sealed trait
的奖励积分,以便编译器可以在您的模式匹配不完整时告诉您:)
我就是这样做的。将 Tree
class 更改为 sealed trait
这意味着模式匹配是详尽无遗的,因此编译器可以告诉您是否遗漏了什么。然后,您需要匹配 Tree 可以是的每种类型。并不是所有的人都有人气。
sealed trait Tree
case object EmptyTree extends Tree
case class Leaf(label: String, popularity: Double) extends Tree
case class Node(popularity: Double, left: Tree, right: Tree) extends Tree
implicit val treeOrdering = new Ordering[Tree] {
private val doubleOrdering = implicitly[Ordering[Double]]
def compare(a: Tree, b: Tree): Int = {
(a, b) match {
case (Node(p1, _, _), Node(p2, _, _)) => doubleOrdering.compare(p1, p2)
case (Leaf(_, p1), Node(p2, _, _)) => doubleOrdering.compare(p1, p2)
case (Node(p1, _, _), Leaf(_, p2)) => doubleOrdering.compare(p1, p2)
case (Leaf(_, p1), Leaf(_, p2)) => doubleOrdering.compare(p1, p2)
case (EmptyTree, _) => -1
case (_, EmptyTree) => 1
}
}
}