Skip to content

Instantly share code, notes, and snippets.

@fedesilva
Last active April 13, 2018 20:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save fedesilva/48f434557f08386cd4b56491b28d0318 to your computer and use it in GitHub Desktop.
Save fedesilva/48f434557f08386cd4b56491b28d0318 to your computer and use it in GitHub Desktop.
A `Monoid` for `Refined` refinement types.
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