【问题标题】:Scala: pattern matching on nested type hierarchiesScala:嵌套类型层次结构上的模式匹配
【发布时间】:2020-03-18 18:19:40
【问题描述】:

假设我有

sealed trait AlphaNumericChar

sealed trait AlphaChar
case object A extends AlphaNumericChar with AlphaChar
case object B extends AlphaNumericChar with AlphaChar

sealed trait NumericChar
case object One extends AlphaNumericChar with NumericChar
case object Two extends AlphaNumericChar with NumericChar

此结构允许我在 AlphaNumericChar 上进行模式匹配并获取所有 A,B,One,Two 并在 AlphaCharNumericChar 上进行类似的模式匹配并仅获取相关对象。

它不允许我写的是:

def foo(x: AlphaNumericChar) = ???
def bar(x: AlphaChar) = foo(x)

即,仅针对某些类型代理对foo 的调用。我当然可以改写:

def baz(x: AlphaNumericChar with AlphaChar) = foo(x) 

这会起作用,但这可能有点难看。

另一种方法是使 AlphaCharNumericChar 扩展 AlphaNumericChar 但这会弄乱我在 AlphaNumericChar 上的模式匹配,因为我现在必须处理 _:AlphaChar_:NumericChar 除了我的案例对象这是不可取的。

有没有办法让两全其美?即。

  • AlphaChar/NumericChar 上的模式匹配条目的详尽列表只有两个元素。
  • AlphaNumericChar 上的模式匹配条目的详尽列表只有两个元素。
  • 我可以让上面的bar 函数工作,而无需使用baz 语法。

【问题讨论】:

    标签: scala pattern-matching hierarchical


    【解决方案1】:

    扩展 AlphaNumericChar 应该不是问题。像这样的东西很好用:

    sealed trait AlphaNumericChar
    
    sealed trait AlphaChar extends AlphaNumericChar
    
    case object A extends AlphaChar
    case object B extends AlphaChar
    
    sealed trait NumericChar extends AlphaNumericChar
    
    case object One extends NumericChar
    case object Two extends NumericChar
    
    def foo(x: AlphaNumericChar) = x match {
      case One => println("hi")
      case Two => println("bye")
      case A => println("foo")
      case B => println("bar")
    }
    
    def bar(x: AlphaChar) = foo(x)
    
    def aThirdFunction(y: NumericChar) = y match {
      case One => println("eggs")
      case Two => println("beans")
    }
    
    foo(One)  // hi
    foo(Two)  // bye
    foo(A)    // foo
    foo(B)    // bar
    bar(A)    // foo
    bar(B)    // bar
    aThirdFunction(One) // eggs
    aThirdFunction(Two) // beans
    

    除非我误解了你想要什么?

    【讨论】:

    • 是的,我想我还不够清楚。我说的是编译器生成的详尽案例列表。我认为您的解决方案是我的第二个选择,但编译器应该警告您foo 中的案例穷举。
    • scastie.scala-lang.org/iaFRC4BARkuIJSeF7I6fgw 这并没有抱怨,但是如果您删除其中一个案例陈述(及其相应的测试),Scastie 会抱怨您的匹配并不详尽。
    • 有趣。我用2.12.10 写了我的例子。但我刚刚用2.12.10 测试了你的例子,这也很好。猜猜这不是编译器的问题,还有一个尝试自动生成我的案例的 IntelliJ 插件。
    • 是的,IntelliJ 并不完美。如果您有任何其他疑问/疑虑,请告诉我。
    猜你喜欢
    • 2011-08-11
    • 1970-01-01
    • 2021-04-30
    • 2012-08-25
    • 2013-09-13
    • 1970-01-01
    • 2017-01-24
    • 2013-11-28
    • 2016-10-21
    相关资源
    最近更新 更多