4

3 つの 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、実装と同じ動作が必要な場合は、これを呼び出すことができます。


余談|+|ですが、最初のモノイド インスタンスorElseは標準ライブラリにあるだけなので、Scalaz を使用しなくてもほぼ同じように簡潔に記述できます。

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

これはもちろん、Scalaz の使用を否定するものではありません。これにより、抽象化をより明確に捉えることができ、最初または最後Someが返されるかどうかに関して動作を変更する洗練された方法が提供されるからです。

于 2012-12-14T17:37:58.150 に答える