Match at least 1 in 3 Scala Regexes using an applicative functor

I have three Scala regular expressions that I need to check to see if any of them match the given String.

I know I can do the following:

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

but I believe there is a way to do this using Applicative Functor or Monad from the Scalaz library.

How can I do that?

+4
source share
1 answer

This is the sum under the β€œfirst” (or β€œlast”) monoid instance for Option . In Scalaz 7 you can write:

 import scalaz._, Scalaz._ val R1 = "[ac]".r val R2 = "[df]".r val R3 = "[gi]".r val m: Option[String] = List(R1, R2, R3).map(_.findFirstIn("test").first).suml 

Or alternatively:

 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 

Note that both of these solutions return the match itself, which you can, of course, call isDefined if you want the same behavior as in your implementation.


As a side note |+| for the first monoid instance, here is just orElse in the standard library, so you can write it almost as concisely as Scalaz:

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

This, of course, is not an argument against using Scalaz, as it allows us to better abstract ourselves and provides an elegant way to change the behavior regarding the return of the first or last Some .

+5
source

All Articles