【问题标题】:Are scala case patterns first class?scala案例模式是一流的吗?
【发布时间】:2012-08-16 11:54:37
【问题描述】:

是否可以将 case 模式作为参数传递给其他函数?像这样的:

def foo(pattern: someMagicType) {
  x match {
    pattern => println("match")
  }
}

def bar() {
  foo(case List(a, b, c))
}

【问题讨论】:

标签: scala pattern-matching first-class


【解决方案1】:

所以你想将模式匹配块传递给另一个函数?这可以通过PartialFunctions 完成,如下例所示:

def foo(f:PartialFunction[String, Int]) = {
  f("")
}

foo {
  case "" => 0
  case s => s.toInt
}

【讨论】:

    【解决方案2】:

    我认为 Kim Stebel 的第一个答案与您想要的很接近。 “模式匹配本身”在 Scala 中不是孤立的实体。匹配可以定义为Function1PartialFunction

    def foo[A, B](x: A)(pattern: PartialFunction[A, B]): Unit =
      if(pattern.isDefinedAt(x)) println("match")
    
    def bar(list: List[String]): Unit =
      foo(list){ case List("a", "b", "c") => }
    

    测试:

    bar(Nil)
    bar(List("a", "b", "c"))
    

    交替使用组合:

    def foo[A, B](x: A)(pattern: PartialFunction[A, B]): Unit = {
      val y = pattern andThen { _ => println("match")}
      if (y.isDefinedAt(x)) y(x)
    }
    

    【讨论】:

      【解决方案3】:

      您的魔法类型可以写成具有 unapply 方法的结构类型。根据您需要的提取器类型,您将需要不同类型的unapplyunapplySeq。下面是一个简单的例子。

      def foo(x:Int, Pattern: { def unapply(x:Int):Boolean }) {
        x match {
          case Pattern => println("match")
        }
      }
      
      foo(1, new { def unapply(x:Int) = x > 0 })
      

      这就是列表的处理方式:

      foo(List(1,2,3), new { def unapplySeq(x:List[Int]):Option[List[Int]] = if (x.size >= 3) Some(x) else None })
      
      def foo(x:List[Int], Pattern: { def unapplySeq(x:List[Int]):Option[List[Int]] }) {
        x match {
          case Pattern(a,b,c) => println("match: " + a + b + c)
        }
      }
      

      【讨论】:

      • foo(1,... 位在 REPL 中不起作用(我使用 2.9.2)。它引导我进行了这个有趣的讨论:scala-lang.org/node/10730
      • 其实编译也行不通。 @Kim,您使用的是哪个版本的 Scala?
      猜你喜欢
      • 1970-01-01
      • 2017-04-25
      • 2013-09-13
      • 2017-02-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-08-12
      • 1970-01-01
      相关资源
      最近更新 更多