2012-12-14 8 views
4

스칼라 정규 표현식 중 3 개가 주어진 문자열과 일치하는지 테스트해야합니다.Applicative Functor를 사용하여 3 가지 스칼라 정규 표현식 중 하나 이상 일치시키기

나는 다음 작업을 수행 할 수 있다는 것을 알고 :

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

하지만 난 Scalaz 라이브러리에서 실용적은 Functor 또는 모나드를 사용하여이 작업을 수행 할 수있는 방법이 있다고 생각합니다.

어떻게이 작업을 수행 할 수 있습니까?

답변

5

Option의 "첫 번째"(또는 "마지막") 모노로이드 인스턴스에서의 합계입니다. 대안

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 

을 또는 : Scalaz 7에서는 쓸 수

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 귀하의 구현에서와 마찬가지로. 물론

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

어느 : 당신이 Scalaz없이 거의 간결이 쓸 수 있도록 보조 노트로


, 여기에 최초의 모노 이드 인스턴스에 대한 |+|, 그냥 표준 라이브러리에서 orElse입니다 Scalaz 사용에 대한 논쟁이 아닙니다. 추상화를 더 깔끔하게 캡처 할 수있게 해주고, 처음 또는 마지막으로 Some이 반환되는지 여부와 관련하여 동작을 변경하는 우아한 방법을 제공합니다.

+0

감사합니다. 나는 Haskell과 Scala에서 Functors, Applicative Functors, Monoids, Monads 모두에 대해 많이 읽었지 만, 머리를 감싸는 것은 여전히 ​​어렵다. – Ralph

+0

'first' 호출을'head'로 변경해야합니까? 'first'는 더 이상 사용되지 않는 것으로 주석 처리됩니다. – Ralph

+3

나는'Seq (R1, R2, R3) .exists (_. findFirstIn ("test"). isDefined)'를 선호한다. 왜냐하면 첫번째 일치를 찾았을 때 멈출 것이기 때문에 더 효율적이다. –