/
option.kt
81 lines (59 loc) · 2.7 KB
/
option.kt
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
package arrow.mtl.instances
import arrow.Kind
import arrow.core.*
import arrow.instance
import arrow.mtl.typeclasses.MonadFilter
import arrow.mtl.typeclasses.TraverseFilter
import arrow.typeclasses.Applicative
import arrow.instances.traverse as optionTraverse
import arrow.instances.traverseFilter as optionTraverseFilter
@instance(Option::class)
interface OptionTraverseFilterInstance : TraverseFilter<ForOption> {
override fun <A> Kind<ForOption, A>.filter(f: (A) -> Boolean): Option<A> =
fix().filter(f)
override fun <G, A, B> Kind<ForOption, A>.traverseFilter(AP: Applicative<G>, f: (A) -> Kind<G, Option<B>>): Kind<G, Option<B>> =
optionTraverseFilter(AP, f)
override fun <A, B> Kind<ForOption, A>.map(f: (A) -> B): Option<B> =
fix().map(f)
override fun <G, A, B> Kind<ForOption, A>.traverse(AP: Applicative<G>, f: (A) -> Kind<G, B>): Kind<G, Option<B>> =
optionTraverse(AP, f)
override fun <A> Kind<ForOption, A>.exists(p: (A) -> Boolean): Boolean =
fix().exists(p)
override fun <A, B> Kind<ForOption, A>.foldLeft(b: B, f: (B, A) -> B): B =
fix().foldLeft(b, f)
override fun <A, B> Kind<ForOption, A>.foldRight(lb: Eval<B>, f: (A, Eval<B>) -> Eval<B>): Eval<B> =
fix().foldRight(lb, f)
override fun <A> OptionOf<A>.forAll(p: (A) -> Boolean): Boolean =
fix().forall(p)
override fun <A> Kind<ForOption, A>.isEmpty(): Boolean =
fix().isEmpty()
override fun <A> Kind<ForOption, A>.nonEmpty(): Boolean =
fix().nonEmpty()
}
@instance(Option::class)
interface OptionMonadFilterInstance : MonadFilter<ForOption> {
override fun <A> empty(): Option<A> =
Option.empty()
override fun <A, B> Kind<ForOption, A>.ap(ff: Kind<ForOption, (A) -> B>): Option<B> =
fix().ap(ff)
override fun <A, B> Kind<ForOption, A>.flatMap(f: (A) -> Kind<ForOption, B>): Option<B> =
fix().flatMap(f)
override fun <A, B> tailRecM(a: A, f: kotlin.Function1<A, OptionOf<Either<A, B>>>): Option<B> =
Option.tailRecM(a, f)
override fun <A, B> Kind<ForOption, A>.map(f: (A) -> B): Option<B> =
fix().map(f)
override fun <A> just(a: A): Option<A> =
Option.just(a)
override fun <A> Kind<ForOption, A>.filter(f: (A) -> Boolean): Option<A> =
fix().filter(f)
}
object OptionMtlContext : OptionMonadFilterInstance, OptionTraverseFilterInstance {
override fun <A> Kind<ForOption, A>.filter(f: (A) -> Boolean): Option<A> =
fix().filter(f)
override fun <A, B> Kind<ForOption, A>.mapFilter(f: (A) -> Option<B>): Option<B> =
flatMap { a -> f(a).fold({ empty<B>() }, { just(it) }) }
override fun <A, B> Kind<ForOption, A>.map(f: (A) -> B): Option<B> =
fix().map(f)
}
infix fun <A> ForOption.Companion.extensions(f: OptionMtlContext.() -> A): A =
f(OptionMtlContext)