在模式匹配中强制推断类型参数的类型绑定

问题描述 投票:0回答:1

我正在尝试编译下面的代码,尽管编译器拒绝它,但它看起来是正确的。我可能做错了什么或者我需要以某种方式提示编译器。

 sealed trait Foo[A]
 
 case class Bar[A, B <: A]() extends Foo[A]
 
 class Visitor[A](foo: Foo[A]) {
   
   def onBar[B <: A](bar: Bar[A, B]) = ???
   
   def run = foo match
     case b: Bar[A, b] => onBar[b](b)

 }

错误是

类型参数 b 不符合上限 A

https://scastie.scala-lang.org/FLvBI6WXS1mdoS1FHhir6A

scala scala-3
1个回答
0
投票

此问题目前正在 scala/scala3#20040 进行讨论,问题代码的有效性将在该报告解决后确认。目前,有两种解决方法:

  1. 如果您可以控制
    Foo
    Bar
    ,您可以编写一个
    fold
    方法来避免模式匹配的需要:
sealed trait Foo[A] {
  def fold[R](caseBar: [B <: A] => Bar[A, B] => R): R
}

case class Bar[A, B <: A]() extends Foo[A] {
  override final def fold[R](caseBar: [B <: A] => Bar[A, B] => R) =
    caseBar[B](this)
}

class Visitor[A](foo: Foo[A]) {

  def onBar[B <: A](bar: Bar[A, B]) = ???

  def run = foo.fold([B <: A] => (b: Bar[A, B]) => onBar[B](b))

}
  1. 您可以添加一个外部
    match
    层,强制编译器记住
    B
    A
    相关:
sealed trait Foo[A]

case class Bar[A, B <: A]() extends Foo[A]

class Visitor[A](foo: Foo[A]) {

  def onBar[B <: A](bar: Bar[A, B]) = ???

  def run = foo match {
    case bar1: Bar[A, ? <: A] =>
      bar1 match {
        case bar2: Bar[A, b] =>
          onBar[b](bar2)
      }
  }

}
© www.soinside.com 2019 - 2024. All rights reserved.