4

我有三个 Scala 正则表达式,我需要测试它们中的任何一个是否与给定的字符串匹配。

我知道我可以做到以下几点:

val matches = R1.findFirstIn(myString).isDefined ||
              R2.findFirstIn(myString).isDefined ||
              R3.findFirstIn(myString).isDefined

但我相信有一种方法可以使用Scalaz库中的 Applicative Functor 或 Monad 来做到这一点。

如何才能做到这一点?

4

1 回答 1

5

这是 的“第一个”(或“最后一个”)幺半群实例下的总和Option。在 Scalaz 7 中,您可以编写:

import scalaz._, Scalaz._

val R1 = "[a-c]".r
val R2 = "[d-f]".r
val R3 = "[g-i]".r

val m: Option[String] = List(R1, R2, R3).map(_.findFirstIn("test").first).suml

或者,或者:

val r1m = R1.findFirstIn("test").first
val r2m = R2.findFirstIn("test").first
val r3m = R3.findFirstIn("test").first

val m: Option[String] = r1m |+| r2m |+| r3m

请注意,这两种解决方案都返回匹配本身,isDefined如果您想要与实现中相同的行为,您当然可以调用它。


附带说明一下,|+|这里的第一个 monoid 实例只是orElse在标准库中,因此您可以在没有 Scalaz 的情况下几乎一样简洁地编写它:

List(R1, R2, R3).map(_.findFirstIn("test")).reduce(_ orElse _)

这当然不是反对使用 Scalaz 的理由,因为它让我们更清晰地捕捉抽象,并提供了一种优雅的方式来改变关于Some返回第一个还是最后一个的行为。

于 2012-12-14T17:37:58.150 回答