Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@raulraja
Last active March 8, 2020 12:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save raulraja/d289db68db94462bfc03811a76810d66 to your computer and use it in GitHub Desktop.
Save raulraja/d289db68db94462bfc03811a76810d66 to your computer and use it in GitHub Desktop.
Arrow Fx. Auto cancels without leaving to user discipline to check for `isAlive`. Examples by @nomisRev
import arrow.fx.*
import arrow.fx.extensions.*
import arrow.fx.typeclasses.*
import arrow.fx.extensions.io.bracket.guaranteeCase
fun <A> IOOf<A>.onCancel(token: IOOf<Unit>): IO<A> =
guaranteeCase { case ->
when (case) {
ExitCase.Canceled -> token
else -> IO.unit
}
}
//sampleStart
fun sleeping(i: Int): IO<Unit> =
IO.effect { println("$i starts sleeping") }
.followedBy(IO.sleep(i.seconds))
.onCancel(IO.effect { println("$i is getting cancelled and woken up!") })
suspend fun main(): Unit = IO.fx {
val (_, cancel) = !listOf(sleeping(1), sleeping(2), sleeping(3))
.parSequence()
.effectMap { println("Finished") }
.fork()
!sleep(1.seconds)
!cancel
}.suspended()
//sampleEnd
/**
2 starts sleeping
1 starts sleeping
3 starts sleeping
3 is getting cancelled and woken up!
2 is getting cancelled and woken up!
1 is getting cancelled and woken up!
**/
import arrow.fx.IO
import arrow.fx.IOOf
import arrow.fx.extensions.fx
import arrow.fx.extensions.io.bracket.guaranteeCase
import arrow.fx.typeclasses.ExitCase
import arrow.fx.typeclasses.seconds
fun <A> IOOf<A>.onCancel(token: IOOf<Unit>): IO<A> =
guaranteeCase { case ->
when (case) {
ExitCase.Canceled -> token
else -> IO.unit
}
}
fun sleeper(): IO<Unit> = IO.fx {
!effect { println("I am sleepy. I'm going to nap") }
!sleep(1.seconds)
!effect { println("1 second nap.. Going to sleep some more") }
!sleeper() //stack safe recursion, infinitely sleeps
}
//sampleStart
suspend fun main(): Unit = IO.fx {
val (_, cancel) = !sleeper()
.onCancel(IO.effect { println("\nSomeone made me wake up from my nap...") })
.fork()
!sleep(3.seconds)
!cancel
}.suspended()
//sampleEnd
/**
I am sleepy. I'm going to nap
1 second nap.. Going to sleep some more
I am sleepy. I'm going to nap
1 second nap.. Going to sleep some more
I am sleepy. I'm going to nap
Someone made me wake up from my nap...
**/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment