Skip to content

Instantly share code, notes, and snippets.

@fteychene
Last active April 2, 2019 15:45
Show Gist options
  • Save fteychene/e82b3d1749f7d9a4088bd0eb57d3a42e to your computer and use it in GitHub Desktop.
Save fteychene/e82b3d1749f7d9a4088bd0eb57d3a42e to your computer and use it in GitHub Desktop.
Polymorphic monad stack test with Arrow
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins {
kotlin("jvm") version "1.3.21"
kotlin("kapt") version "1.3.21"
}
repositories {
mavenCentral()
}
val arrowVersion = "0.9.0"
dependencies {
implementation(kotlin("stdlib"))
compile("io.arrow-kt:arrow-core-data:$arrowVersion")
compile("io.arrow-kt:arrow-core-extensions:$arrowVersion")
compile("io.arrow-kt:arrow-syntax:$arrowVersion")
compile("io.arrow-kt:arrow-typeclasses:$arrowVersion")
compile("io.arrow-kt:arrow-extras-data:$arrowVersion")
compile("io.arrow-kt:arrow-extras-extensions:$arrowVersion")
kapt("io.arrow-kt:arrow-meta:$arrowVersion")
compile("io.arrow-kt:arrow-effects-data:$arrowVersion")
compile("io.arrow-kt:arrow-effects-extensions:$arrowVersion")
compile("io.arrow-kt:arrow-effects-io-extensions:$arrowVersion")
compile("io.arrow-kt:arrow-optics:$arrowVersion")
compile("io.arrow-kt:arrow-effects-rx2-data:$arrowVersion")
compile("io.arrow-kt:arrow-effects-rx2-extensions:$arrowVersion")
compile("io.reactivex.rxjava2:rxjava:2.2.8")
compile("io.arrow-kt:arrow-effects-reactor-data:$arrowVersion")
compile("io.arrow-kt:arrow-effects-reactor-extensions:$arrowVersion")
compile("io.projectreactor:reactor-core:3.2.8.RELEASE")
testCompile("junit", "junit", "4.12")
}
configure<JavaPluginConvention> {
sourceCompatibility = JavaVersion.VERSION_1_8
}
tasks.withType<KotlinCompile> {
kotlinOptions.jvmTarget = "1.8"
}
import arrow.data.EitherT
import arrow.data.extensions.eithert.monad.monad
import arrow.data.fix
import arrow.effects.IO
import arrow.effects.extensions.io.monadDefer.monadDefer
import arrow.effects.fix
import arrow.effects.reactor.FluxK
import arrow.effects.reactor.MonoK
import arrow.effects.reactor.extensions.fluxk.monadDefer.monadDefer
import arrow.effects.reactor.extensions.monok.monadDefer.monadDefer
import arrow.effects.reactor.fix
import arrow.effects.rx2.ObservableK
import arrow.effects.rx2.SingleK
import arrow.effects.rx2.extensions.observablek.monadDefer.monadDefer
import arrow.effects.rx2.extensions.singlek.monadDefer.monadDefer
import arrow.effects.rx2.fix
import arrow.effects.typeclasses.MonadDefer
fun <F> loadValue(MDF: MonadDefer<F>, value: Int): EitherT<F, String, Int> = EitherT.just(MDF, value)
fun <F> insertInDatabase(MDF: MonadDefer<F>, value: Int): EitherT<F, String, String> = EitherT.just(MDF, value.toString())
fun <F> log(MDF: MonadDefer<F>, log: String): EitherT<F, String, Unit> =
EitherT.liftF(MDF, MDF.delay { println(log) })
fun <F> domainLogic(MDF: MonadDefer<F>, initialValue: Int): EitherT<F, String, String> =
EitherT.monad<F, String>(MDF).run {
binding {
log(MDF, "Load value").bind()
val result = loadValue(MDF, initialValue)
.map(MDF) { it * 2 }.bind()
log(MDF, "Insert in database").bind()
insertInDatabase(MDF, result).bind()
}.fix()
}
fun main() {
println("Run with Arrow IO")
val io = domainLogic(IO.monadDefer(), 60).value().fix()
io.attempt().unsafeRunAsync { println(it)}
println()
println("Run with RxJava Single")
val single = domainLogic(SingleK.monadDefer(), 60).value().fix()
single.single.subscribe(::println, ::println)
println()
println("Run with RxJava Observable")
val observable = domainLogic(ObservableK.monadDefer(), 60).value().fix()
observable.observable.subscribe(::println, ::println)
println()
println("Run with Reactor Mono")
val mono = domainLogic(MonoK.monadDefer(), 60).value().fix()
mono.mono.subscribe(::println, ::println)
println()
println("Run with Reactor Flux")
val flux = domainLogic(FluxK.monadDefer(), 60).value().fix()
flux.flux.subscribe(::println, ::println)
println()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment