我问earlier question我得到了一个很好的答案。在评论中,Travis提到比较两个HandValue
不会直接起作用,但可以使用模式匹配来确保比较同一个类。
sealed abstract class HandValue[T <: HandValue[T]](val rank: Int) extends Ordered[T]
case class HighCard(high: Int) extends HandValue[HighCard](0){
def compare(that: HighCard) = this.high - that.high
}
case class TwoPair(high: Int, big: Int, sm: Int) extends HandValue[TwoPair](2) {
def compare (that: TwoPair) = { ... }
}
在下面尝试的模式匹配中,我有一个编译时错误,我怀疑它与使用HandValue[_]
有关。 val h1: HandValue[T <: HandValue[T]]
类似于声明类型的方式,无效。有办法解决这些问题吗?
val ans = sessions count {
hands: (Hand, Hand) => {
val h1: HandValue[_] = handValue(hands._1)
val h2: HandValue[_] = handValue(hands._2)
(h1, h2) match { // <-- Line as source of error
case _ if h1.rank > h2.rank => true
case (a: HighCard, b: HighCard) => a > b
case (a: TwoPair, b: TwoPair) => a > b
// etc..
}
}
}
编辑:编译时错误是:
error: type arguments [_$3] do not conform to class HandValue's type parameter bounds [T <: euler.solutions.p54.HandValue[T]]
(h1, h2) match {
编辑2:正如this question中所述,使用Type[_]
将无效。
答案 0 :(得分:2)
无法帮助解决错误,但您可以通过允许将任何HandValue
与任何其他HandValue
进行比较来消除大量此类复杂性;然后你不必有可怕的参数化和重复的compare
方法,然后是ans
中重复的比较逻辑。
一种方法是让每一个定义一个strength
,这是一个Seq[Int]
,由手牌排名,后面是手牌中定义其力量的牌的等级组成。然后,您只需比较这些Seqs
,找出哪个数字首先有更大的数字,即
sealed abstract class HandValue(val strength: Seq[Int]) extends Ordered[HandValue] {
import math.Ordering.Implicits.seqDerivedOrdering
def compare(that: HandValue) =
Ordering[Seq[Int]].compare(this.strength, that.strength)
}
case class HighCard(high1: Int, high2: Int, high3: Int, high4: Int, high5: Int )
extends HandValue(Seq(0, high1, high2, high3, high4, high5))
case class TwoPair(high: Int, big: Int, sm: Int)
extends HandValue(Seq(2, big, sm, high))
val ans = sessions count { hands =>
handValue(hands._1) > handValue(hands._2)
}
注意,在计算高牌手牌强度时,您需要考虑所有牌。还要留意Ace-to-5直!
您也可以使用散列函数将strength
计算为Int
(正如我在执行此问题时所做的那样:https://gist.github.com/3270831)。