Skip to content

Instantly share code, notes, and snippets.

@dnene
Last active April 8, 2018 08:36
Show Gist options
  • Save dnene/bb0a1d93b73d23122dae4aa5a806b72f to your computer and use it in GitHub Desktop.
Save dnene/bb0a1d93b73d23122dae4aa5a806b72f to your computer and use it in GitHub Desktop.
Applicatives, Functors and Monads using Kotlin and Arrow
import arrow.core.*
import arrow.data.k
import arrow.syntax.applicative.tupled
import arrow.syntax.functor.map
import arrow.typeclasses.binding
typealias IntFunction = (Int) -> Int
fun IntFunction.map(g: IntFunction) = { it: Int -> this(g(it)) }
object Main {
@JvmStatic
fun main(args: Array<String>) {
mapOverOption()
mapOverFunction()
applicative()
applicativeList()
tripleProduct()
halfMonad()
}
fun mapOverOption() {
println(Some(2).map { it + 3 })
val none: Option<Int> = None
println(none.map { it + 3})
println(listOf(Some(3), None).map { it.map { it + 3} })
}
fun mapOverFunction() {
val add3 = { it: Int -> it + 3 }
val double = { it: Int -> it * 2 }
println(double.map(add3)(3))
}
fun applicative() {
val add3: Option<(Int) -> Int> = Some({ it: Int -> it + 3 })
val result = Option.applicative().tupled(add3, Some(3)).map { it.a(it.b)}
val result2 = Option.applicative().run { Some(3).ap(Some<(Int)->Int>({ it -> it + 2})) }
println(result)
println(result2)
}
fun applicativeList() {
val add3 = { it: Int -> it + 3 }
val double = { it: Int -> it * 2 }
val result = Option.applicative().run { listOf(2,3).k().ap(listOf<(Int)->Int>({it + 3}, {it * 2}).k()) }
println(result)
}
fun tripleProduct() {
println(Option.applicative().tupled(Some(2), Some(3), Some(4)).map { it.a * it.b * it.c })
println(Option.applicative().tupled(Some(2), None as Option<Int>, Some(4)).map { it.a * it.b * it.c })
}
fun halfMonad() {
val half = { n: Int -> if (n % 2 == 0) Some(n/2) else None}
println(half(5))
println(half(6))
fun monadComprehension(o: Option<Int>) =
Option.monad().binding {
val a = o.bind()
val b = half(a).bind()
b
}
println(monadComprehension(Some(5)))
println(monadComprehension(Some(6)))
println(monadComprehension(None))
// alternative approach
println(Some(5).flatMap(half))
println(Some(6).flatMap(half))
println(None.flatMap(half))
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment