Last active
April 13, 2018 20:46
-
-
Save fedesilva/48f434557f08386cd4b56491b28d0318 to your computer and use it in GitHub Desktop.
A `Monoid` for `Refined` refinement types.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package we.sg.data | |
import cats.kernel.Monoid | |
import eu.timepit.refined.{W, refineMV, refineV} | |
import eu.timepit.refined.api.Refined | |
import eu.timepit.refined.boolean.Not | |
import eu.timepit.refined.string.MatchesRegex | |
object RefinementTypes { | |
/** Predicate that proves a String contains upper case chars */ | |
type WithUppercase = MatchesRegex[W.`".*([A-Z]).*"`.T] | |
/** Predicate that proves a String contains NO upper case chars */ | |
type NoUppercase = Not[MatchesRegex[W.`".*([A-Z]).*"`.T]] | |
/** String which is proven to contain no upper case chars */ | |
type StringNoUppercase = String Refined NoUppercase | |
/** Helper function to avoid excessive imports */ | |
def strNoUppercase(str: String): Either[String, StringNoUppercase] = | |
refineV[NoUppercase](str) | |
/** Helper value, we use it to concatenate with other `StringNoUppercase` values */ | |
val UnderscoreNoUppercase: StringNoUppercase = refineMV[NoUppercase]("_") | |
/** Helper value, we use it to concatenate with other `StringNoUppercase` values */ | |
val EmptyNoUppercase: StringNoUppercase = refineMV[NoUppercase]("") | |
/** Provides a `Monoid` for any `Refined` instance whose underlaying value has a `Monoid` instance itself | |
* | |
* You will probably need to `import cats.implicits._` to get instances for common types. | |
* | |
*/ | |
implicit def refinedMonoid[T : Monoid, P]: Monoid[Refined[T, P]] = | |
new Monoid[Refined[T, P]] { | |
private val monoid = implicitly[Monoid[T]] | |
override def empty: Refined[T, P] = Refined.unsafeApply[T,P](monoid.empty) | |
override def combine(x: Refined[T, P], y: Refined[T, P]): Refined[T, P] = | |
Refined.unsafeApply[T,P](monoid.combine(x.value,y.value)) // Both are safe, so we unsafeApply and sleep soundly. | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment