Scala模式匹配提取器的右结合性

3

我目前正在尝试使用Scala的模式匹配。目前我所知道的是,以操作符命名的提取器是左结合的,而以方法或类型命名的提取器是右结合的。

我的当前方法大致如下:

object Foo {
  def unapply(tokens: Seq[String]): Option[(Seq[String], String)] = // do something
}

// ...

object Main extends App {
  Seq("hi", "bye") match {
    case xs Foo foo2 Foo foo1 => // do something with result
    case _ => // handle error
  }
}

这有点让人不太愉快,因为我需要反向写我的匹配项或反向匹配它们,这是由于右结合性导致的。如果可以的话,我更喜欢像这样写:

object Foo {
   def unapply(tokens: Seq[String]): Option[(String, Seq[String])] = // do something
}

// ...

object Main extends App {
  Seq("hi", "bye") match {
    case foo1 Foo foo2 xs => // do something with result
    case _ => // handle error
  }
}

有没有办法为提取器保留一些易读的名称并使其左联想?

谢谢您的帮助。

2个回答

5
你需要以:结尾来命名你的类名。
根据Scala规范Infix Operations, 6.12.3),运算符的结合性由其最后一个字符决定:
以冒号:结尾的运算符是右结合的。所有其他运算符都是左结合的。
例如:
scala> object `Foo:` {
         def unapply(tokens: Seq[String]): Option[(String, Seq[String])] =
           Some((tokens.head, tokens.tail))
       }
defined object Foo$colon

scala> Seq("hi", "bye", "world") match {
         case foo1 `Foo:` foo2 `Foo:` foo3 =>  println(s"$foo1 $foo2 $foo3")
       }
hi bye List(world)

很不幸,由于Foo:不是有效的标识符,您需要使用反引号。


1
啊,谢谢,这就是我要找的!只要规则本身仍然可读,反引号对我来说并不成问题。 - bash0r

0

我不确定我是否理解问题,但我认为您正在寻求类似于这样的东西:

object Foo {
  def unapply(tokens: Seq[String]): Option[(String, Seq[String])] =
      Some((tokens.head, tokens.tail))
  }

// ...

object Main extends App {
  Seq("hi", "bye") match {
    case foo1 Foo foo2 =>  println(s">> $foo1 $foo2")
    case _ => println("error") // handle error
  }
}

1
这是我想要的行为。唯一的问题是: 当你链接它时,它会立即失效,因为Foo是右结合的。 - bash0r

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接