2012-08-06 57 views
1

我問了一個earlier question我收到了很好的答案。在評論中,Travis提到,比較兩個不會直接工作,但可以使用模式匹配來確保比較同一個類。Scala:解決不明確的模式匹配類型

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

什麼是編譯時錯誤? – pedrofurla 2012-08-06 02:07:01

+0

對不起,很好的電話!我忘了粘貼它。 – Louis 2012-08-06 02:08:27

+0

順便說一下,Hand和HandValue之間的關係是什麼? – pedrofurla 2012-08-06 03:29:29

回答

2

無法幫助解決該錯誤,但您可以通過允許任何與其他進行比較來消除很多此複雜性;那麼您不必擁有可怕的參數化方法並重復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)。

+0

我最終做了類似於你的建議 - 謝謝! – Louis 2012-08-08 01:15:41