2017-05-24 10 views
1

나는 스칼라 순서에 암시 적으로 문제가있다. 누군가 나를 도울 수 있는가?스칼라 암시 적 변환을 주문 하시겠습니까?

다음은 몇 가지 클래스 정의입니다. 내가하고 싶은 것은 Leaf와 Node를 'popularity'를 통해 비교하는 것입니다. exampel에 대한

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) 
} 

그러나 만약 내가 그것을 통해 c를 비교하기를 원한다면 나는 혼란스럽고 암묵적인 변환을 추가하는 방법을 모른다.

나를 도와 줄 사람이 있습니까?

+0

귀하의 질문은 다소 모호합니다. 귀하의 제목은 암시 적 질서에 대해 이야기하지만 암시 적 전환을 찾고있는 것처럼 보입니까? –

+0

당신은'새로운 주문 [나무] '를 만들 수 있습니다 –

+0

타일을 수정합니다. @ YuvalItzchakov – Yang

답변

1

Id 다음과 같이하십시오. Tree 클래스를 sealed trait으로 변경하면 패턴 일치가 철저하므로 컴파일러가 누락 된 항목을 알 수 있음을 의미합니다. 그런 다음 트리가 될 수있는 각 유형을 일치시켜야합니다. 그들 모두가 인기가있는 것은 아닙니다.

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 
    } 
    } 

} 
+0

감사합니다. 귀하의 방법을 시도하고 있습니다. – Yang

+0

안녕하세요, 사전에 감사드립니다. 예제에서 코드를 테스트하려고하면 "리프에 정의 된 암시 적 순서가 없습니다."라는 메시지가 나타납니다. 다음은 나의 예입니다 : val a = Leaf ("a", 3) val b = Leaf ("b", 5) val e = 리프 ("e", 6) val c = 노드 (10, a, b) 의 Val D = 노드 (11, C, A) 브로 S = 배열 ​​(e는 A, B)이 암시 '로 변경 – Yang

+0

'브로 treeOrdering = ... '를 .sorted 브로 treeOrdering = ...' – Stephen

2

LeafNode을 비교하려면 Tree에 대해 암시적인 Ordering을 생성 할 수 있습니다. 여기

은 당신이 할 수있는 방법에 대한 몇 가지 (불완전한) 코드이다 : 당신의 패턴 매칭가 불완전 할 때 컴파일러는 당신을 말할 수 있도록하는 sealed trait을 할 Tree을 변경

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 */ 
    } 
} 

보너스 포인트를 :)

+0

고마워, 암호. – Yang

+0

안녕하세요 Luka, 사전에 감사드립니다, 내 예제에서 코드를 테스트 할 때 "Leaf에 정의 된 암시 적 순서가 없습니다."라는 메시지가 나타납니다. 아래 예제는 다음과 같습니다 : val a = Leaf ("a", 3) val b = Leaf ("b", 5) val e = 리프 ("e", 6) val c = 노드 (10, a, b) val d = Node (11, c, a) val s = Array (e, a, b). 배열 – Yang

+0

흠, 저에게 효과적입니다. –