/
Identity.scala
202 lines (130 loc) · 6.47 KB
/
Identity.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
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
package scalaz
import annotation.tailrec
sealed trait Identity[A] extends Equals with IdentitySugar[A] {
def value: A
import Scalaz._
def ok = Value(value)
def pure[F[_]](implicit p: Pure[F]): F[A] = p pure value
def dual: Dual[A] = DualTo(value)
def |+|(a: => A)(implicit s: Semigroup[A]): A = s append (value, a)
def ===(a: A)(implicit e: Equal[A]): Boolean = e equal (value, a)
def /==(a: A)(implicit e: Equal[A]): Boolean = !(===(a))
/**
* Returns `a` if it is non-null, otherwise returns `d`.
*/
def ??(d: => A)(implicit ev: Null <:< A): A = Option(value) getOrElse d
/**
* Raises an error if `value ≠ b`, according to the given `Equal`. The message is formated with the given `Show`.
*/
// using the implicit parameter ev here gives better compiler error messages for mistyped expressions like 1 assert_=== "".
// the simpler signature is def assert_===(b: A)(implicit e: Equal[A], s: Show[A])
def assert_===[B](b: B)(implicit e: Equal[A], s: Show[A], ev: B <:< A) = if (≠(b)) error_(shows + " ≠ " + ev(b).shows)
def ?|?(a: A)(implicit o: Order[A]): Ordering = o order (value, a)
def lte(a: A)(implicit o: Order[A]): Boolean = o.order(value, a) != GT
def gte(a: A)(implicit o: Order[A]): Boolean = o.order(value, a) != LT
def lt(a: A)(implicit o: Order[A]): Boolean = o.order(value, a) == LT
def gt(a: A)(implicit o: Order[A]): Boolean = o.order(value, a) == GT
def min(a: A)(implicit o: Order[A]): A = if (lte(a)) value else a
def max(a: A)(implicit o: Order[A]): A = if (gte(a)) value else a
def show(implicit s: Show[A]): List[Char] = s.show(value)
def shows(implicit s: Show[A]): String = s.show(value).mkString
def print(implicit s: Show[A]): Unit = Console.print(shows)
def println(implicit s: Show[A]): Unit = Console.println(shows)
def mapply[F[_], B](f: F[A => B])(implicit ftr: Functor[F]): F[B] = f ∘ (_(value))
def |>[B](f: A => B): B = f(value)
def text(implicit s: Show[A]): xml.Text = xml.Text(value.shows)
def <===>(a: A)(implicit m: MetricSpace[A]): Int = m distance (value, a)
def constantState[S](s: => S): State[S, A] = Scalaz.state((_: S) => (s, value))
def state[S]: State[S, A] = Scalaz.state((_: S, value))
def unfold[M[_], B](f: A => Option[(B, A)])(implicit p: Pure[M], m: Monoid[M[B]]): M[B] = f(value) match {
case None => m.zero
case Some((b, a)) => b.η ⊹ a.unfold(f)
}
def replicate[M[_]](n: Int, f: A => A = a => a)(implicit p: Pure[M], m: Monoid[M[A]]): M[A] = {
@tailrec
def replicate0(accum: M[A], n: Int, a: A): M[A] = if (n > 0) replicate0(accum ⊹ a.η, n - 1, f(a)) else accum
replicate0(∅, n, value)
}
def repeat[M[_]](implicit p: Pure[M], m: Monoid[M[A]]): M[A] = value.η ⊹ repeat
def iterate[M[_]](f: A => A)(implicit p: Pure[M], m: Monoid[M[A]]): M[A] =
value.η ⊹ f(value).iterate(f)
def zipper: Zipper[A] = Scalaz.zipper(Stream.empty, value, Stream.empty)
def unfoldTree[B](f: A => (B, () => Stream[A])): Tree[B] = f(value) match {
case (a, bs) => Scalaz.node(a, bs.apply.unfoldForest(f))
}
def unfoldTreeM[B, M[_]](f: A => M[(B, Stream[A])])(implicit m: Monad[M]): M[Tree[B]] = {
m.bind(f(value), (abs: (B, Stream[A])) =>
m.bind(abs._2.unfoldForestM[B, M](f), (ts: Stream[Tree[B]]) =>
m.pure(Scalaz.node(abs._1, ts))))
}
def node(subForest: Tree[A]*): Tree[A] = Scalaz.node(value, subForest.toStream)
def leaf: Tree[A] = Scalaz.leaf(value)
def success[X]: Validation[X, A] = Scalaz.success(value)
def successNel[X]: ValidationNEL[X, A] = success
def fail[X]: Validation[A, X] = failure(value)
def failNel[X]: ValidationNEL[A, X] = failure(wrapNel)
def some: Option[A] = Some(value)
def pair: (A, A) = (value, value)
def squared: (A, A) = pair
def left[B]: Either[A, B] = Left(value)
def right[B]: Either[B, A] = Right(value)
def wrapNel: NonEmptyList[A] = Scalaz.nel(value)
/**
* @return the result of pf(value) if defined, otherwise the the Zero element of type B.
*/
def matchOrZero[B: Zero](pf: PartialFunction[A, B]): B = ~pf.lift(value)
@tailrec
final def doWhile(f: A => A, p: A => Boolean): A = {
val x = f(value)
if (p(x)) x.doWhile(f, p) else x
}
@tailrec
final def whileDo(f: A => A, p: A => Boolean): A =
if (p(value)) f(value).whileDo(f, p) else value
/** A pair lazy in its right value, with this value on the left and the given value on the right. */
def <&>[B](b: => B): (A :&: B) = lazyTuple(value, b)
/** Convert the value into a monoid */
def unit[M](implicit r: Reducer[A,M]): M = r.unit(value)
/** Convert the value into a monoid in a pointed functor */
def pureUnit[M[_], N](implicit m: Pure[M], r: Reducer[A,N]): M[N] = unit[N].pure
/** Append the value to a monoid for use in left-to-right reduction */
def snoc[C](c: C)(implicit r: Reducer[C,A]): A = r.snoc(value, c)
/** Prepend the value to a monoid for use in right-to-left reduction */
def cons[M](m: M)(implicit r: Reducer[A,M]): M = r.cons(value, m)
/** Constructs a writer with the given value for writing */
def set[W](w: W): Writer[W, A] =
writer[W, A](w, value)
/** Attaches a logger to this value, which accepts log values of the given type L */
def logger[L]: Logger[L, A] =
mkLogger(value)
override def toString: String = value.toString
override def hashCode: Int = value.hashCode
override def equals(o: Any): Boolean = canEqual(o) && value == o.asInstanceOf[Identity[_]].value
def canEqual(o: Any): Boolean = o != null && o.isInstanceOf[Identity[_]]
}
object Identity {
def apply[A](a: => A): Identity[A] = new Identity[A] {
lazy val value = a
}
def unapply[A](v: Identity[A]): Option[A] = Some(v.value)
}
trait Identitys {
implicit def mkIdentity[A](x: => A): Identity[A] = Identity(x)
implicit def unMkIdentity[A](x: Identity[A]): A = x.value
val unital = mkIdentity(())
}
sealed trait IdentitySugar[A] {
self: Identity[A] =>
/** Alias for {@link scalaz.Identity#pure} */
def η[F[_]](implicit p: Pure[F]): F[A] = pure
/** Alias for {@link scalaz.Identity#dual} */
def σ : Dual[A] = dual
/** Alias for {@link scalaz.Identity#|+|} */
def ⊹(a: => A)(implicit s: Semigroup[A]): A = |+|(a)
/** Alias for {@link scalaz.Identity#===} */
def ≟(a: A)(implicit e: Equal[A]): Boolean = ===(a)
/** Alias for {@link scalaz.Identity#/==} */
def ≠(a: A)(implicit e: Equal[A]): Boolean = /==(a)
/** Alias for assert_=== */
def assert_≟[B](b: B)(implicit e: Equal[A], s: Show[A], ev: B <:< A) = assert_===(b)
}