forked from scalaz/scalaz
-
Notifications
You must be signed in to change notification settings - Fork 0
/
OneOr.scala
311 lines (247 loc) · 8.36 KB
/
OneOr.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
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
package scalaz
/** @since 7.0.3 */
final case class OneOr[F[_], A](run: F[A] \/ A) {
def map[B](f: A => B)(implicit F: Functor[F]): OneOr[F, B] =
OneOr(run.bimap(F.map(_)(f), f))
def ap[B](f: OneOr[F, A => B])(implicit F: Apply[F]): OneOr[F, B] =
OneOr(f.run match {
case -\/(g) =>
run match {
case -\/(h) =>
-\/(F.ap(h)(g))
case \/-(h) =>
-\/(F.map(g)(_(h)))
}
case \/-(g) =>
run match {
case -\/(h) =>
-\/(F.map(h)(g))
case \/-(h) =>
\/-(g(h))
}
})
def cojoin(implicit F: Cobind[F]): OneOr[F, OneOr[F, A]] =
OneOr(run match {
case \/-(_) =>
\/-(this)
case -\/(a) =>
-\/(F.extend(a)(t => OneOr(-\/(t))))
})
def cobind[B](f: OneOr[F, A] => B)(implicit F: Cobind[F]): OneOr[F, B] =
OneOr(run match {
case \/-(_) =>
\/-(f(this))
case -\/(a) =>
-\/(F.cobind(a)(t => f(OneOr(-\/(t)))))
})
def copoint(implicit F: Comonad[F]): A =
run valueOr F.copoint
def foldMap[B](f: A => B)(implicit M: Monoid[B], F: Foldable[F]): B =
run match {
case \/-(a) =>
f(a)
case -\/(a) =>
F.foldMap(a)(f)
}
def foldRight[B](z: => B)(f: (A, => B) => B)(implicit F: Foldable[F]): B =
run match {
case \/-(a) =>
f(a, z)
case -\/(a) =>
F.foldRight(a, z)(f)
}
def foldLeft[B](z: => B)(f: (B, A) => B)(implicit F: Foldable[F]): B =
run match {
case \/-(a) =>
f(z, a)
case -\/(a) =>
F.foldLeft(a, z)(f)
}
def foldMap1[B](f: A => B)(implicit M: Semigroup[B], F: Foldable1[F]): B =
run match {
case \/-(a) =>
f(a)
case -\/(a) =>
F.foldMap1(a)(f)
}
def foldMapRight1[B](z: A => B)(f: (A, => B) => B)(implicit F: Foldable1[F]): B =
run match {
case \/-(a) =>
z(a)
case -\/(a) =>
F.foldMapRight1(a)(z)(f)
}
def foldMapLeft1[B](z: A => B)(f: (B, A) => B)(implicit F: Foldable1[F]): B =
run match {
case \/-(a) =>
z(a)
case -\/(a) =>
F.foldMapLeft1(a)(z)(f)
}
def traverse[G[_], B](f: A => G[B])(implicit T: Traverse[F], F: Applicative[G]): G[OneOr[F, B]] =
run match {
case \/-(a) =>
F.map(f(a))(t => OneOr(\/-(t)))
case -\/(a) =>
F.map(T.traverse(a)(f))(t => OneOr(-\/(t)))
}
def traverse1[G[_], B](f: A => G[B])(implicit T: Traverse1[F], F: Apply[G]): G[OneOr[F, B]] =
run match {
case \/-(a) =>
F.map(f(a))(t => OneOr(\/-(t)))
case -\/(a) =>
F.map(T.traverse1(a)(f))(t => OneOr(-\/(t)))
}
}
private sealed trait OneOrFunctor[F[_]]
extends Functor[({type λ[α] = OneOr[F, α]})#λ] {
implicit def F: Functor[F]
override def map[A, B](fa: OneOr[F, A])(f: A => B): OneOr[F, B] =
fa map f
}
private sealed trait OneOrCobind[F[_]]
extends OneOrFunctor[F] with Cobind[({type λ[α] = OneOr[F, α]})#λ] {
implicit def F: Cobind[F]
override def cobind[A, B](fa: OneOr[F, A])(f: OneOr[F, A] => B): OneOr[F, B] =
fa cobind f
}
private sealed trait OneOrComonad[F[_]]
extends OneOrCobind[F] with Comonad[({type λ[α] = OneOr[F, α]})#λ] {
implicit def F: Comonad[F]
override def cobind[A, B](fa: OneOr[F, A])(f: OneOr[F, A] => B): OneOr[F, B] =
fa cobind f
override def copoint[A](fa: OneOr[F, A]) =
fa.copoint
}
private sealed trait OneOrApplicative[F[_]]
extends OneOrFunctor[F] with Applicative[({type λ[α] = OneOr[F, α]})#λ] {
implicit def F: Apply[F]
override def ap[A,B](fa: => OneOr[F, A])(f: => OneOr[F, A => B]) =
fa ap f
override def point[A](a: => A) =
OneOr(\/-(a))
}
private sealed trait OneOrFoldable[F[_]]
extends Foldable[({type λ[α] = OneOr[F, α]})#λ] {
implicit def F: Foldable[F]
override def foldMap[A, B](fa: OneOr[F, A])(f: A => B)(implicit M: Monoid[B]) =
fa.foldMap(f)
override def foldRight[A, B](fa: OneOr[F, A], z: => B)(f: (A, => B) => B) =
fa.foldRight(z)(f)
override def foldLeft[A, B](fa: OneOr[F, A], z: B)(f: (B, A) => B) =
fa.foldLeft(z)(f)
}
private sealed trait OneOrFoldable1[F[_]]
extends OneOrFoldable[F] with Foldable1[({type λ[α] = OneOr[F, α]})#λ] {
implicit def F: Foldable1[F]
override def foldMap1[A, B](fa: OneOr[F, A])(f: A => B)(implicit M: Semigroup[B]) =
fa.foldMap1(f)
override def foldMapRight1[A, B](fa: OneOr[F, A])(z: A => B)(f: (A, => B) => B) =
fa.foldMapRight1(z)(f)
override def foldMapLeft1[A, B](fa: OneOr[F, A])(z: A => B)(f: (B, A) => B) =
fa.foldMapLeft1(z)(f)
}
private sealed trait OneOrTraverse[F[_]]
extends OneOrFunctor[F] with OneOrFoldable[F] with Traverse[({type λ[α] = OneOr[F, α]})#λ] {
implicit def F: Traverse[F]
override def traverseImpl[G[_]: Applicative,A,B](fa: OneOr[F, A])(f: A => G[B]) =
fa traverse f
override def foldMap[A, B](fa: OneOr[F, A])(f: A => B)(implicit M: Monoid[B]) =
fa.foldMap(f)
}
private sealed trait OneOrTraverse1[F[_]]
extends OneOrFoldable1[F] with OneOrTraverse[F] with Traverse1[({type λ[α] = OneOr[F, α]})#λ] {
implicit def F: Traverse1[F]
override def traverse1Impl[G[_]: Apply,A,B](fa: OneOr[F, A])(f: A => G[B]) =
fa traverse1 f
}
private sealed trait OneOrEqual[F[_], A] extends Equal[OneOr[F, A]] {
implicit def OA: Equal[A]
implicit def OFA: Equal[F[A]]
override def equal(a1: OneOr[F, A], a2: OneOr[F, A]) =
a1.run === a2.run
override def equalIsNatural = OA.equalIsNatural && OFA.equalIsNatural
}
private sealed trait OneOrOrder[F[_], A] extends Order[OneOr[F, A]] {
implicit def OA: Order[A]
implicit def OFA: Order[F[A]]
override def order(a1: OneOr[F, A], a2: OneOr[F, A]) =
a1.run compare a2.run
}
private sealed trait OneOrShow[F[_], A] extends Show[OneOr[F, A]] {
implicit def OA: Show[A]
implicit def OFA: Show[F[A]]
override def show(a: OneOr[F, A]) =
a.run.show
}
object OneOr extends OneOrInstances with OneOrFunctions
trait OneOrFunctions {
type OneOrList[A] = OneOr[List, A]
type OneOrNel[A] = OneOr[NonEmptyList, A]
type OneOrOption[A] = OneOr[Option, A]
type OneOrId[A] = OneOr[Id.Id, A]
type OneOrNothing[A] = OneOr[Nothing, A]
}
sealed abstract class OneOrInstances extends OneOrInstances0 {
implicit def OneOrFunctor[F[_]: Functor]: Functor[({type λ[α] = OneOr[F, α]})#λ] =
new OneOrFunctor[F] {
def F = implicitly
}
implicit def OneOrEqual[F[_], A](implicit oa: Equal[A], ofa: Equal[F[A]]): Equal[OneOr[F, A]] =
new OneOrEqual[F, A] {
def OA = implicitly
def OFA = implicitly
}
implicit def OneOrShow[F[_], A](implicit oa: Show[A], ofa: Show[F[A]]): Show[OneOr[F, A]] =
new OneOrShow[F, A] {
def OA = implicitly
def OFA = implicitly
}
}
sealed abstract class OneOrInstances0 extends OneOrInstances1 {
implicit def OneOrCobind[F[_]: Cobind]: Cobind[({type λ[α] = OneOr[F, α]})#λ] =
new OneOrCobind[F] {
def F = implicitly
}
implicit def OneOrOrder[F[_], A](implicit oa: Order[A], ofa: Order[F[A]]): Order[OneOr[F, A]] =
new OneOrOrder[F, A] {
def OA = implicitly
def OFA = implicitly
}
}
sealed abstract class OneOrInstances1 extends OneOrInstances2 {
implicit def OneOrComonad[F[_]: Comonad]: Comonad[({type λ[α] = OneOr[F, α]})#λ] =
new OneOrComonad[F] {
def F = implicitly
}
}
sealed abstract class OneOrInstances2 extends OneOrInstances3 {
implicit def OneOrApplicative[F[_]: Apply]: Applicative[({type λ[α] = OneOr[F, α]})#λ] =
new OneOrApplicative[F] {
def F = implicitly
}
}
sealed abstract class OneOrInstances3 extends OneOrInstances4 {
implicit def OneOrFoldable[F[_]: Foldable]: Foldable[({type λ[α] = OneOr[F, α]})#λ] =
new OneOrFoldable[F] {
def F = implicitly
}
}
sealed abstract class OneOrInstances4 extends OneOrInstances5 {
implicit def OneOrFoldable1[F[_]: Foldable1]: Foldable1[({type λ[α] = OneOr[F, α]})#λ] =
new OneOrFoldable1[F] {
def F = implicitly
}
}
sealed abstract class OneOrInstances5 extends OneOrInstances6 {
implicit def OneOrTraverse[F[_]: Traverse]: Traverse[({type λ[α] = OneOr[F, α]})#λ] =
new OneOrTraverse[F] {
def F = implicitly
}
}
sealed abstract class OneOrInstances6 {
implicit def OneOrTraverse1[F[_]: Traverse1]: Traverse1[({type λ[α] = OneOr[F, α]})#λ] =
new OneOrTraverse1[F] {
def F = implicitly
}
}