2012-08-06 3 views
1

Я спросил earlier question, на который я получил отличный ответ. В комментариях Трэвис упомянул, что сравнение двух s не будет работать напрямую, но сопоставление шаблонов может использоваться для сравнения одного и того же класса.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.. 
     } 
    } 
    } 

Edit: Ошибка компиляции время:

error: type arguments [_$3] do not conform to class HandValue's type parameter bounds [T <: euler.solutions.p54.HandValue[T]] 
(h1, h2) match { 

Edit 2: Как упоминалось в this question, используя Type[_] не будет работать.

+0

Какова ошибка времени компиляции? – pedrofurla

+0

Ах, извините, хороший звонок! Я забыл вставить его. – Louis

+0

Кстати, какова связь между Hand и HandValue? – pedrofurla

ответ

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

Смежные вопросы