1
1
package com.fortyseven.fpfundamentals
2
2
3
+ import arrow.extension
3
4
import arrow.higherkind
5
+ import com.fortyseven.fpfundamentals.maybe.combinator.combinator
4
6
5
7
// Data types
6
8
7
9
@higherkind
8
10
sealed class Maybe <out A > : MaybeOf <A > {
11
+ companion object {
12
+ }
13
+
9
14
data class Present <A >(val a : A ) : Maybe<A>()
10
15
object Absent : Maybe<Nothing>()
11
16
12
- inline fun <B > fold (ifAbsent : () -> B , ifSome : (A ) -> B ): B = when (this ) {
17
+ inline fun <B > fold (ifAbsent : () -> B , ifPresent : (A ) -> B ): B = when (this ) {
13
18
is Absent -> ifAbsent()
14
- is Present <A > -> ifSome(a)
19
+ is Present <A > -> ifPresent(a)
20
+ }
21
+ }
22
+
23
+ // Typeclasses
24
+
25
+ interface Combinator <A > {
26
+
27
+ fun combine (x : A , y : A ): A
28
+ }
29
+
30
+ // Instances
31
+
32
+ @extension
33
+ interface IntCombinator : Combinator <Int > {
34
+ override fun combine (x : Int , y : Int ): Int = x + y
35
+ }
36
+
37
+ fun Int.Companion.combinator (): Combinator <Int > =
38
+ object : IntCombinator {}
39
+
40
+ @extension
41
+ interface MaybeCombinator <A > : Combinator <Maybe <A >> {
42
+
43
+ fun CA (): Combinator <A >
44
+
45
+ override fun combine (x : Maybe <A >, y : Maybe <A >): Maybe <A > {
46
+ return x.fold(
47
+ { y },
48
+ { xx ->
49
+ y.fold(
50
+ { x },
51
+ { yy -> Maybe .Present (CA ().combine(xx, yy)) })
52
+ })
15
53
}
16
54
}
17
55
@@ -24,7 +62,8 @@ class Program {
24
62
fun getBalanceBank2 (): Maybe <Int > = Maybe .Present (80 )
25
63
26
64
val balance: Maybe <Int >
27
- get() = getBalanceBank1() + getBalanceBank2() // It won't compile
65
+ get() = Maybe .combinator(Int .combinator())
66
+ .combine(getBalanceBank1(), getBalanceBank2())
28
67
}
29
68
30
69
fun main (args : Array <String >) {
0 commit comments