Case classes matching in Scala

喜你入骨 提交于 2019-12-08 09:25:52

问题


I want to have this comparison function that matches two case classes, but it's a bit verbose.

Leafs are always in the sorted order in the List.

  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 sortCodeTreeFun(x: CodeTree, y: CodeTree) = {
    (x, y) match {
      case (x1: Leaf, y1: Leaf) => true
      case (x1: Fork, y1: Leaf) => x1.weight < y1.weight
      case (x1: Leaf, y1: Fork) => x1.weight < y1.weight
      case (x1: Fork, y1: Fork) => x1.weight < y1.weight
    }
  }

I tried to modify CodeTree constructor to be:

  abstract class CodeTree(weight: Int)

So that I can compare x and y directly, but compiler says:

"not enough arguments for constructor CodeTree: (weight: Int)patmat.Huffman.CodeTree"

Is there another way to shorten sortCodeTreeFun method?


回答1:


You could simply say:

def sortCodeTreeFun(x: CodeTree, y: CodeTree) = {
  (x, y) match {
    case (_: Leaf, _: Leaf)           => true
    case (x1: CodeTree, y1: CodeTree) => x1.weight < y1.weight
  }
}

And define abstract class CodeTree as

abstract class CodeTree {
  def weight: Int
}

The reason for the error is that when you extend an class that take a parameter you need to supply the parameter. So for

abstract class CodeTree(weight: Int)

You need to extend it as

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

That's what the error you were getting was saying:

"not enough arguments for constructor CodeTree: (weight: Int)"

It was because you weren't supplying the required argument weight when extending CodeTree.

The problem with this approach though is that weight is not a member of CodeTree and hence can not to be accessed from an instance of type CodeTree. That is to say, if you did:

 scala> Fork(...).asInstanceOf[CodeTree].weight
 <console>:11: error: value weight is not a member of CodeTree

So, in your pattern match, you wouldn't be able to do x1.weight since the type of x1 is a CodeTree and CodeTree does not have a weight.




回答2:


If you want to sort elements like codetrees, you can use Sorting.stableSort



来源:https://stackoverflow.com/questions/13039472/case-classes-matching-in-scala

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!