Last active
February 26, 2019 15:44
-
-
Save raulraja/62de72039b11b05ed6d472cb8178da0c to your computer and use it in GitHub Desktop.
Kotlin transformers encoding for `Death of Final Tagless` by John De Goes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package arrow.effects.zio.example | |
/** Capabilities aggregation ala Kotlin **/ | |
class Capabilities( | |
console: Console, | |
random: Random | |
) : Console by console, Random by random |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package arrow.effects.zio.example | |
/** Console capability **/ | |
interface Console { | |
fun <R> console(): Service<R> | |
companion object { | |
/** Algebra **/ | |
interface Service<R> { | |
fun putStrLn(line: String): RIO<R, Unit> | |
fun getStrLn(): RIO<R, String> | |
} | |
interface Live : Console { | |
/** Interpreter **/ | |
override fun <R> console(): Service<R> = object : Service<R> { | |
override fun putStrLn(line: String): RIO<R, Unit> = | |
rio { println(line) } | |
override fun getStrLn(): RIO<R, String> = | |
rio { readLine().orEmpty() } | |
} | |
companion object : Live | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package arrow.effects.zio.example | |
/** Runtime implementation **/ | |
object DefaultRuntime : Runtime<Capabilities> { | |
override val Environment: Capabilities | |
get() = Capabilities( | |
Console.Companion.Live, | |
Random.Companion.Live | |
) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package arrow.effects.zio.example | |
import arrow.core.Either | |
sealed class CustomError | |
object Stop : CustomError() | |
typealias Result<A> = Either<Throwable, Either<CustomError, A>> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package arrow.effects.zio.example | |
/** Concrete program **/ | |
fun <R> program(): RIO<R, Unit> where R : Console, R : Random = | |
fx { | |
val mod: R = services() | |
val randomNumber = !mod.random<R>().randomInt() | |
!mod.console<R>().putStrLn("Found random int: $randomNumber") | |
!Stop.raiseError<R, Unit>() | |
} | |
/** Unsafe edge **/ | |
fun main() { | |
val result: Result<Unit> = DefaultRuntime.unsafeRunBlocking(program()) | |
println(result) | |
} | |
//Found random int: 1829110450 | |
//Right(b=Left(a=arrow.effects.zio.Stop@726f3b58)) | |
//Process finished with exit code 0 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package arrow.effects.zio.example | |
import arrow.core.right | |
import arrow.data.* | |
import arrow.data.extensions.kleisli.monadError.monadError | |
import arrow.data.extensions.monadError | |
import arrow.effects.ForIO | |
import arrow.effects.IO | |
import arrow.effects.extensions.io.monad.monad | |
import arrow.typeclasses.Monad | |
import arrow.typeclasses.MonadContinuation | |
import arrow.typeclasses.MonadError | |
import kotlin.coroutines.startCoroutine | |
/** Arrow boilerplate since we don't have a ZIO<R, D, A> **/ | |
typealias CustomErrors = EitherTPartialOf<ForIO, CustomError> | |
typealias RIO<R, A> = ReaderT<CustomErrors, R, A> | |
val ioMonad: Monad<ForIO> = IO.monad() | |
val errorMonad: MonadError<EitherTPartialOf<ForIO, CustomError>, CustomError> = EitherT.monadError(ioMonad) | |
fun <R> F(): MonadError<KleisliPartialOf<EitherTPartialOf<ForIO, CustomError>, R>, CustomError> = ReaderT.monadError(errorMonad) | |
typealias FxContinuation<R, A> = MonadContinuation<ReaderTPartialOf<EitherTPartialOf<ForIO, CustomError>, R>, A> | |
fun <R, A> fx(fa: suspend FxContinuation<R, *>.() -> A): RIO<R, A> { | |
val continuation: FxContinuation<R, A> = FxContinuation(F()) | |
val wrapReturn: suspend FxContinuation<R, *>.() -> RIO<R, A> = { just(fa()).fix() } | |
wrapReturn.startCoroutine(continuation, continuation) | |
return continuation.returnedMonad().fix() | |
} | |
fun <R, A> CustomError.raiseError(): RIO<R, A> = | |
F<R>().run { | |
this@raiseError.raiseError<A>().fix() | |
} | |
suspend fun <R> FxContinuation<R, *>.services(): R = | |
!Kleisli.ask<EitherTPartialOf<ForIO, CustomError>, R>(errorMonad).fix() | |
fun <R, A> rio(fa: () -> A): RIO<R, A> = | |
ReaderT { EitherT(IO { fa().right() }) } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package arrow.effects.zio.example | |
/** Random Capability **/ | |
interface Random { | |
fun <R> random(): Service<R> | |
companion object { | |
interface Service<R> { | |
fun randomInt(): RIO<R, Int> | |
} | |
interface Live : Random { | |
override fun <R> random(): Service<R> = | |
object : Service<R> { | |
override fun randomInt(): RIO<R, Int> = | |
rio { java.util.Random().nextInt() } | |
} | |
companion object : Live | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package arrow.effects.zio.example | |
import arrow.data.fix | |
import arrow.effects.fix | |
/** Runtime module **/ | |
interface Runtime<R> { | |
val Environment: R | |
fun <A> unsafeRunBlocking(rio: RIO<R, A>): Result<A> = | |
rio.run(Environment).fix().value().fix().attempt().unsafeRunSync() | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment