Hello everyone! I started experimenting with Arrow...
# arrow
m
Hello everyone! I started experimenting with Arrow Fx
0.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:
Copy code
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:
Copy code
{
  "b": [
    {
      "id": 2,
      "firstName": "Matt",
      "lastName": "Moore"
    }
  ]
}
With
EitherT
:
Copy code
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:
Copy code
[
  {
    "id": 2,
    "firstName": "Matt",
    "lastName": "Moore"
  }
]
Note that it no longer wraps in
b
Apologies for the long message!
s
Hey, The API is still a bit sluggish, that’s the part we’re still stream lining.
suspended()
here is still returning
Right(b: B)
.
IO<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
.
Copy code
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))
suspended
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.