mattmoore
02/04/2020, 5:45 PM0.11.0-SNAPSHOT last night using Ktor. I switched from EitherT over to IO<E, A> and got everything compiling and running. The weird thing is that with IO<E, A> if I respond with A in Ktor (where A is the successful data class I'm expecting), A gets serialized with { "b": { ... } } .
At first I thought I had something still wrapped, but I inspected all the functions and types and still am getting that result. When I downgraded back to 0.10.4 and switched back to EitherT the response serializes properly without b and instead serializes to { ... } . Curious if anyone else has encountered this.
Here's an example:
fun getLeads(): IO<Exception, List<Lead>> =
IO.fx<Exception, List<Lead>> {
transaction {
Leads.selectAll().map { toLead(it) }
}
}
val response = getLeads().attempt().map {
when (it) {
is Either.Left -> mapOf("error" to it.a.message)
is Either.Right -> present(it.b)
}
}
call.respond(response.suspended())
It's entirely possible I'm misusing attempt here, not sure. The Ktor serialized response I get is:
{
"b": [
{
"id": 2,
"firstName": "Matt",
"lastName": "Moore"
}
]
}
With EitherT :
fun getLeads(): EitherT<ForIO, Exception, List<Lead>> = EitherT(
IO {
Right(
transaction {
Leads.selectAll().map { toLead(it) }
}
)
}.handleError { Left(Exception(it.message)) }
)
val response = getLeads().value().fix().map {
when (it) {
is Either.Left -> mapOf("error" to it.a.message)
is Either.Right -> present(it.b)
}
}.suspended()
call.respond(response)
When I run this example with EitherT I get this response from Ktor:
[
{
"id": 2,
"firstName": "Matt",
"lastName": "Moore"
}
]
Note that it no longer wraps in b
Apologies for the long message!simon.vergauwen
02/04/2020, 6:33 PMsuspended() here is still returning Right(b: B).simon.vergauwen
02/04/2020, 6:35 PMIO<E, A> is by all means EitherT<ForIO which means it deals with Throwable, E & A.
The semantics of attempt have not changed, which is attempt to run it and lift the Throwable to A.
val t: IO<E, A>
val t2: IO<E, Either<Throwable, A>>
val t3: IO<Nothing, IOResult<E, A>> = t.result()
val t4: IO<Nothing, A> = t.fallbackWith(IO.just(backupA))simon.vergauwen
02/04/2020, 6:35 PMsuspended currently always returns Either<E, A> I think the snapshot has a suspendedGet for IO<Nothing, A> which you could use after providing a fallback default value.