Skip to content

Instantly share code, notes, and snippets.

@ckozak
Last active April 1, 2016 16:38
Show Gist options
  • Save ckozak/4ef04f1af93de112b46c31898149faec to your computer and use it in GitHub Desktop.
Save ckozak/4ef04f1af93de112b46c31898149faec to your computer and use it in GitHub Desktop.
import cats.data.Validated.{Invalid, Valid}
import cats.{Applicative, Apply, Semigroup, SemigroupK}
import cats.data.{NonEmptyList, Validated, ValidatedNel}
import cats.std.list._
sealed abstract class ConfigError
final case class MissingConfig(field: String) extends ConfigError
case class Person(name: String, lastName: String)
val valid1: Validated[ConfigError, String] = Validated.Valid("valid1")
val valid2: Validated[ConfigError, String] = Validated.Valid("valid2")
val invalid1: Validated[ConfigError, String] = Validated.Invalid(MissingConfig("invalid3"))
val valid3: Validated[ConfigError, String] = Validated.Valid("valid3")
implicit val nelSemigroup: Semigroup[NonEmptyList[ConfigError]] =
SemigroupK[NonEmptyList].algebra[ConfigError]
implicit def validatedApplicative[E : Semigroup]: Applicative[Validated[E, ?]] =
new Applicative[Validated[E, ?]] {
def ap[A, B](f: Validated[E, A => B])(fa: Validated[E, A]): Validated[E, B] =
(fa, f) match {
case (Valid(a), Valid(fab)) => Valid(fab(a))
case (i@Invalid(_), Valid(_)) => i
case (Valid(_), i@Invalid(_)) => i
case (Invalid(e1), Invalid(e2)) => Invalid(Semigroup[E].combine(e1, e2))
}
def pure[A](x: A): Validated[E, A] = Validated.valid(x)
def map[A, B](fa: Validated[E, A])(f: A => B): Validated[E, B] = fa.map(f)
def product[A, B](fa: Validated[E, A], fb: Validated[E, B]): Validated[E, (A, B)] =
ap(fa.map(a => (b: B) => (a, b)))(fb)
}
val person: ValidatedNel[ConfigError, Person] =
Apply[ValidatedNel[ConfigError, String]].map2(
valid1.toValidatedNel,
valid2.toValidatedNel
) {
case (left, right, one, two) => Person(left, right)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment