1

我问了一个较早的问题,我得到了很好的答案。在评论中,Travis 提到比较两个HandValues 不能直接工作,但是可以使用模式匹配来确保比较同一个类。

  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:正如在这个问题中提到的,使用Type[_]不起作用。

4

1 回答 1

2

无法解决错误,但您可以通过允许将 anyHandValue与任何其他 进行比较来消除很多这种复杂性HandValue;那么你就不必再有那个可怕的参数化和重复compare方法,然后是重复的比较逻辑ans

一种方法是让每个人定义 a 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 )。

于 2012-08-06T05:19:00.440 回答