Last active
January 6, 2019 19:15
-
-
Save bjonnh/e7358781df1137da59fec6f37d0ee163 to your computer and use it in GitHub Desktop.
How to run suspend function in Arrow IOs
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
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