Skip to content

Instantly share code, notes, and snippets.

@bjonnh
Last active January 6, 2019 19:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save bjonnh/e7358781df1137da59fec6f37d0ee163 to your computer and use it in GitHub Desktop.
Save bjonnh/e7358781df1137da59fec6f37d0ee163 to your computer and use it in GitHub Desktop.
How to run suspend function in Arrow IOs
import arrow.effects.IO
import arrow.effects.coroutines.DeferredK
import arrow.effects.coroutines.extensions.deferredk.applicativeError.handleError
import arrow.effects.extensions.io.async.async
import arrow.effects.extensions.io.monad.binding
import arrow.effects.fix
import kotlinx.coroutines.delay
import java.time.LocalDateTime
sealed class KnownError : RuntimeException()
object NonExistentReference : KnownError()
object DecodingError : KnownError()
data class UnManagedReturnCode(val status: Int) : KnownError()
data class Call(val a: String, val b: String, val status: Int, val content: String)
suspend fun call(url: String): Call {
delay(1000L)
return Call("10", "2", 200, "{\"value\": \"foo\"}")
}
data class JsonObj(val value: String)
class ArrowTrial {
var lastRun: LocalDateTime = LocalDateTime.now()
var delay: Long = 50
fun calcDelay(): Long {
println("Calculating delay")
return 100L
} // mocked
fun updateDelayFromHeaderData(a: String, b: String) {
println("Updating Delay")
delay = a.toLong() / b.toLong()
} // mocked
fun updateLastQueryTime() = { LocalDateTime.now() }
suspend fun ObjFromJson(content: String): JsonObj? {
delay(1000L)
return JsonObj("Hero")
} // mocked
fun worksFromDoi(doi: String): IO<JsonObj> =
binding {
IO.async().delay {
calcDelay()
}.bind()
DeferredK<Call> {
call("$doi")
}.map { call ->
IO.async().delay {
updateDelayFromHeaderData(
call.a,
call.b
)
}
IO.async().delay { updateLastQueryTime() }
when (call.status) {
200 -> IO<JsonObj> {
// How do I get a value out of that
ObjFromJson(call.content) ?: JsonObj("failed")
}
404 -> IO.raiseError<JsonObj>(NonExistentReference)
else -> IO.raiseError<JsonObj>(UnManagedReturnCode(call.status))
}
// getCompleted is obviously not the way to go here
}.handleError { IO.raiseError<JsonObj>(DecodingError) }.value().getCompleted()
}.fix().unsafeRunSync()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment