-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathday5.scala
69 lines (52 loc) · 1.5 KB
/
day5.scala
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
65
66
67
68
package day5
import scala.language.implicitConversions // eyeroll
import scala.language.higherKinds
import scalaz._
import Scalaz._
import scalacheck.ScalazProperties._
import scalacheck.ScalazArbitrary._
import scalacheck.ScalaCheckBinding._
import org.scalacheck._
sealed trait Maybe[+A]
case object Nada extends Maybe[Nothing]
case class Just[A](a: A) extends Maybe[A]
object Maybe {
implicit def equal[A: Equal]: Equal[Maybe[A]] =
new Equal[Maybe[A]] {
def equal(a: Maybe[A], b: Maybe[A]): Boolean = a == b
}
implicit val monad: Monad[Maybe] =
new Monad[Maybe] {
def point[A](a: => A): Maybe[A] = Just(a)
def bind[A, B](fa: Maybe[A])(f: A => Maybe[B]): Maybe[B] =
fa match {
case Nada => Nada
case Just(a) => f(a)
}
}
val genMaybeInt: Gen[Maybe[Int]] =
for {
x <- Arbitrary.arbitrary[Int]
a <- Gen.oneOf(Nada, Just(x))
} yield a
implicit val arbitraryMaybeInt: Arbitrary[Maybe[Int]] =
Arbitrary(genMaybeInt)
val genMaybeIntInt: Gen[Maybe[Int => Int]]=
for {
x <- Arbitrary.arbitrary[Int => Int]
a <- Gen.oneOf(Nada, Just(x))
} yield a
implicit val arbitraryMaybeIntToInt: Arbitrary[Maybe[Int => Int]] =
Arbitrary(genMaybeIntInt)
}
object Main extends App {
// Bind operators
println("## Bind operators")
import Maybe.monad.monadSyntax._
println(Just(21) >>= { x => Just(x*2) })
// Monad laws
println("## Monad laws")
monad.laws[Maybe].check
println("")
println("")
}