This repository was archived by the owner on Feb 14, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 10
/
Copy pathTimeFun.scala
78 lines (56 loc) · 1.74 KB
/
TimeFun.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
69
70
71
72
73
74
75
76
77
78
package scalaz.reactive
import scalaz.reactive.Time._
import scalaz.{ Applicative, Functor, Monad }
import scalaz.reactive.TimeFun.{ Fun, K }
/**
* A function of time. It has functor, applicative, and monad instances
*/
sealed trait TimeFun[+A] {
def apply: Time.T => A
def map[B](f: A => B): TimeFun[B] =
this match {
case K(a) => K(f(a))
case Fun(g) => Fun(f.compose(g))
}
def ap[B](f: TimeFun[A => B]): TimeFun[B] =
(f, this) match {
case (K(g), K(a)) => K(g(a))
case (K(g), Fun(f)) => Fun(g.compose(f))
case (Fun(g), h) => Fun(t => g(t)(h.apply(t)))
}
def flatMap[B](f: A => TimeFun[B]): TimeFun[B] =
this match {
case K(a) => f(a)
case Fun(g) => Fun(t => f(g(t)).apply(t))
}
}
object TimeFun extends TimeFunFunctions with TimeFunInstances {
case class K[+A](a: A) extends TimeFun[A] {
def apply: T => A = _ => a
}
case class Fun[+A](f: T => A) extends TimeFun[A] {
def apply: T => A = f
}
}
trait TimeFunFunctions {
def point[A](a: => A): TimeFun[A] =
K(a)
}
trait TimeFunInstances {
implicit def functorTimeFun: Functor[TimeFun] = new Functor[TimeFun] {
override def map[A, B](fa: TimeFun[A])(f: A => B): TimeFun[B] =
fa.map(f)
}
implicit def applicativeTimeFun: Applicative[TimeFun] =
new Applicative[TimeFun] {
override def point[A](a: => A): TimeFun[A] = TimeFun.point(a)
override def ap[A, B](fa: => TimeFun[A])(f: => TimeFun[A => B]): TimeFun[B] =
fa.ap(f)
}
def monadTimeFun: Monad[TimeFun] =
new Monad[TimeFun] {
override def point[A](a: => A): TimeFun[A] = TimeFun.point(a)
override def bind[A, B](fa: TimeFun[A])(f: A => TimeFun[B]): TimeFun[B] =
fa.flatMap(f)
}
}