-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcats-execise-data-validation2.sc
64 lines (56 loc) · 1.88 KB
/
cats-execise-data-validation2.sc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
import $ivy.`org.typelevel::cats-core:2.0.0`
import cats.Semigroup
import cats.instances.all._
import cats.syntax.either._
import cats.syntax.semigroup._
sealed trait Check[E, A] {
import Check._
def and(that: Check[E, A]): Check[E, A] = {
And(this, that)
}
def apply(a: A)(implicit s: Semigroup[E]): Either[E, A] = {
this match {
case Pure(func) => func(a)
case And(left, right) => {
(left(a), right(a)) match {
case (Left(e1), Left(e2)) => (e1 |+| e2).asLeft
case (Right(_), Left(e)) => e.asLeft
case (Left(e), Right(_)) => e.asLeft
case (Right(_), Right(_)) => a.asRight
}
}
}
}
}
object Check {
final case class And[E, A](left: Check[E, A], right: Check[E, A]) extends Check[E, A]
final case class Pure[E, A](func: A => Either[E, A]) extends Check [E, A]
def pure[E, A](func: A => Either[E, A]): Check[E, A] = Pure(func)
}
// final case class CheckF[E, A](func: A => Either[E, A]) {
// def apply(a: A): Either[E, A] = func(a)
// def and(that: CheckF[E, A])(implicit s: Semigroup[E]): CheckF[E, A] = {
// CheckF { a =>
// (this(a), that(a)) match {
// case (Left(e1), Left(e2)) => (e1 |+| e2).asLeft
// case (Right(_), Left(e)) => e.asLeft
// case (Left(e), Right(_)) => e.asLeft
// case (Right(_), Right(_)) => a.asRight
// }
// }
// }
// }
val a: Check[List[String], Int] =
Check.pure { v =>
if(v > 2) v.asRight
else List("Must be > 2").asLeft
}
val b: Check[List[String], Int] =
Check.pure { v =>
if(v < -2) v.asRight
else List("Must be < -2").asLeft
}
val check: Check[List[String], Int] =
a and b
println(check(5))
println(check(0))