Skip to content

Instantly share code, notes, and snippets.

@daneko
Last active March 10, 2019 13:11
Show Gist options
  • Save daneko/ef38e95fec2ae97de20973a5d006dc0f to your computer and use it in GitHub Desktop.
Save daneko/ef38e95fec2ae97de20973a5d006dc0f to your computer and use it in GitHub Desktop.
migration 0.8.2 to 0.9.0 (is this correct? please tell me recommended code!)
// using 0.9.0
import arrow.Kind
import arrow.core.Either
import arrow.core.Try
import arrow.core.left
import arrow.core.right
import arrow.data.EitherT
import arrow.effects.ForIO
import arrow.effects.IO
import arrow.effects.coroutines.DeferredK
import arrow.effects.coroutines.ForDeferredK
import arrow.effects.coroutines.extensions.deferredk.async.async
import arrow.effects.coroutines.unsafeAttemptSync
import arrow.effects.extensions.io.async.async
import arrow.effects.fix
import arrow.effects.rx2.ForSingleK
import arrow.effects.rx2.SingleK
import arrow.effects.rx2.extensions.singlek.async.async
import arrow.effects.rx2.unsafeRunSync
import arrow.effects.typeclasses.Async
import arrow.typeclasses.MonadThrow
import arrow.typeclasses.suspended.monaderror.Fx
fun main() {
val deferredKResult: Try<Either<SampleError, Unit>> = SampleWithDeferredK.exec().value().unsafeAttemptSync()
val singleKResult: Try<Either<SampleError, Unit>> = Try {
SampleWithSingleK.exec().value().unsafeRunSync()
}
val IOResult: Try<Either<SampleError, Unit>> = Try {
SampleWithIO.exec().value().fix().unsafeRunSync()
}
println(deferredKResult)
println(singleKResult)
println(IOResult)
}
object SampleWithDeferredK : Sample<ForDeferredK>, Async<ForDeferredK> by DeferredK.async() {
override fun monadError(): MonadThrow<ForDeferredK> {
return DeferredK.async()
}
}
object SampleWithSingleK : Sample<ForSingleK>, Async<ForSingleK> by SingleK.async() {
override fun monadError(): MonadThrow<ForSingleK> {
return SingleK.async()
}
}
object SampleWithIO : Sample<ForIO>, Async<ForIO> by IO.async() {
override fun monadError(): MonadThrow<ForIO> {
return IO.async()
}
}
interface Sample<F> : MonadThrow<F>, Fx<F> {
private fun sometimeThrow(): Kind<F, Unit> = Math.random().let {
when {
it < 0.1 -> raiseError(RuntimeException("not handling"))
it < 0.3 -> raiseError(Exception("need handling"))
else -> just(Unit)
}
}
fun exec(): EitherT<F, SampleError, Unit> {
val kind = fx {
!sometimeThrow()
.handleErrorWith {
when (it) {
is RuntimeException -> raiseError(it)
is Exception -> raiseError(SampleError.Error1("get error"))
else -> raiseError(it)
}
}
// ...
Unit.right()
}.handleErrorWith {
if (it is SampleError) just(it.left())
else raiseError(it)
}
return EitherT(kind)
}
}
sealed class SampleError : Exception() {
data class Error1(val msg: String) : SampleError()
// ...
}
// using 0.8.2
import arrow.Kind
import arrow.core.Either
import arrow.core.Try
import arrow.core.left
import arrow.core.right
import arrow.data.EitherT
import arrow.effects.*
import arrow.effects.deferredk.async.async
import arrow.effects.instances.io.async.async
import arrow.effects.singlek.async.async
import arrow.effects.typeclasses.Async
import arrow.typeclasses.MonadThrow
fun main() {
val deferredKResult: Try<Either<SampleError, Unit>> = SampleWithDeferredK.exec().value().unsafeAttemptSync()
val singleKResult: Try<Either<SampleError, Unit>> = Try {
SampleWithSingleK.exec().value().value().blockingGet()
}
val IOResult: Try<Either<SampleError, Unit>> = Try {
SampleWithIO.exec().value().fix().unsafeRunSync()
}
println(deferredKResult)
println(singleKResult)
println(IOResult)
}
object SampleWithDeferredK : Sample<ForDeferredK>, Async<ForDeferredK> by DeferredK.async()
object SampleWithSingleK : Sample<ForSingleK>, Async<ForSingleK> by SingleK.async()
object SampleWithIO : Sample<ForIO>, Async<ForIO> by IO.async()
interface Sample<F> : MonadThrow<F> {
private fun sometimeThrow(): Kind<F, Unit> = Math.random().let {
when {
it < 0.1 -> raiseError(RuntimeException("not handling"))
it < 0.3 -> raiseError(Exception("need handling"))
else -> just(Unit)
}
}
fun exec(): EitherT<F, SampleError, Unit> {
val kind = binding {
sometimeThrow()
.handleErrorWith {
when (it) {
is RuntimeException -> raiseError(it)
is Exception -> raiseError(SampleError.Error1("get error"))
else -> raiseError(it)
}
}.bind()
// ...
Unit.right()
}.handleErrorWith {
if (it is SampleError) just(it.left())
else raiseError(it)
}
return EitherT(kind)
}
}
sealed class SampleError : Exception() {
data class Error1(val msg: String) : SampleError()
// ...
}
// https://kotlinlang.slack.com/archives/C5UPMM0A0/p1552222607217100
// thank you raul!
// using 0.9.0
import arrow.Kind
import arrow.core.Either
import arrow.core.left
import arrow.core.right
import arrow.effects.extensions.io.monadDefer.monadDefer
import arrow.effects.extensions.io.unsafeRun.runBlocking
import arrow.effects.typeclasses.MonadDefer
import arrow.effects.typeclasses.suspended.monaddefer.Fx
import arrow.unsafe
/** Errors **/
sealed class SampleError : Exception() {
data class Error1(val msg: String) : SampleError()
// don't recompute stack traces
override fun fillInStackTrace(): Throwable = this
// ...
}
/** Algebra **/
interface Sample<F> : Fx<F> {
private fun sometimeThrow(): Kind<F, Unit> =
fx {
val rd = !delay { Math.random() }
!when {
rd < 0.1 -> RuntimeException("not handling").raiseError()
rd < 0.3 -> Exception("need handling").raiseError()
else -> unit()
}
}
private fun program(): Kind<F, Unit> =
fx {
!sometimeThrow().handleErrorWith {
when (it) {
is RuntimeException -> it.raiseError()
is Exception -> SampleError.Error1("get error").raiseError()
else -> it.raiseError()
}
}
}
fun exec(): Kind<F, Either<SampleError, Unit>> =
fx {
val attempted = !program().attempt()
attempted.fold(
{
if (it is SampleError) it.left()
else throw it //you choose not to handle these
},
{ it.right() }
)
}
}
/** Runtime proofs **/
object IORuntime : Sample<ForIO> {
override fun monadDefer(): MonadDefer<ForIO> =
IO.monadDefer()
}
/** Runtime **/
fun main() {
val result: Either<SampleError, Unit> =
unsafe { runBlocking { IORuntime.exec() } }
println(result)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment