首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Scala:解决模式匹配的二义性类型

Scala:解决模式匹配的二义性类型
EN

Stack Overflow用户
提问于 2012-08-06 09:47:44
回答 1查看 243关注 0票数 1

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

代码语言:javascript
复制
  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]]是无效的。有没有办法解决这些问题?

代码语言:javascript
复制
  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..
      }
    }
  }

编辑:编译时错误是:

代码语言:javascript
复制
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[_]是行不通的。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-08-06 13:19:00

我不能帮助纠正这个错误,但是您可以通过允许将任何HandValue与任何其他HandValue进行比较来消除这种复杂性;这样您就不必使用可怕的参数化和重复的compare方法,然后在ans中使用重复的比较逻辑。

一种方法是让每个人定义一个strength,它是一个Seq[Int],它由手牌等级组成,后面跟着定义其强度的手牌等级。然后,您只需比较这些Seqs,找出哪个数字先出现,即

代码语言:javascript
复制
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)。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11821675

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档