A follow up to my earlier question on Rx with Arro...
# arrow
m
A follow up to my earlier question on Rx with Arrow. I'm trying to write a comprehension that combines calls to functions that return Rx Single objects. For example:
Copy code
class ArrowRxTests {
    @Test
    fun `comprehension with arrow and rx`() {
        val x = SingleK.fx {
            val (count) = getCountSingle       // this is an async call using a SingleK.monadDefer
            val newCount = increment(count)    // this is an async call returning Single<Int>.... how do i use it here?
            newCount
        }.value()

        assertThat(x.blockingGet()).isEqualTo(2)
    }

    private fun getCount() = 1
    private fun <F> getCountAsync(MS: MonadDefer<F>) = MS.later { getCount() }
    private val getCountSingle: SingleKOf<Int> = getCountAsync(SingleK.monadDefer())

    private fun increment(i: Int): Single<Int> = Single.just(i + 1)
}
This works if
increment
just returns an int, but how do I use increment() in the comprehension when it already returns a Single? I want to somehow keep the flow of the code inside
SingleK.fx {}
but using functions that return Rx types
s
What you’re doing in the first line is “extracting” the value from
getCountSingle
using
operator fun component1()
or destructuring.
This is an alias for the functions
operator fun not()
or
fun bind()
. So
val (count) = getCountSingle
is the same as
val count = getCountSingle.bind()
or
val count = !getCountSingle
.
So you can do the same thing for
increment
.
Copy code
val x = SingleK.fx {
  val count = !getCountSingle
  val newCount = !increment(count)
  newCount
}.value()
m
how do I import the "!"? it's not coming up for me
s
It should be available within
fx
It’s enabled through the
receiver
AsyncSyntax<ForSingle>
which should be the scope of
this
within
fx
.
m
message has been deleted
j
Is there some sort of function from
Single -> SingleK
like
k()
? because that is what you need first^^
s
Oh my bad. Those are only available for
SingleK
.
We need to add binds for concrete types in
Syntax
classes for wrappers such as
arrow-fx-rx
and
arrow-fx-reactor
I’m afraid this requires changes in Arrow, but I’d be happy to help you implement them if you’re interested in contributing @Mark Fisher
m
!increment(count).k()
worked
s
Yes! That works because the operations are defined for
Kind<ForSingleK, A>
and not for
Single<A>
directly.
All of this boilerplate will be gone with arrow-meta, and these confusing situations cannot occur anymore.
m
how far is meta off btw?
and many thanks for the help on this!
s
I think a preview will become available soon. I am not 100% sure, but #arrow-meta will be able to give you a better answer. Everyone there is working hard and it’s progressing too fast for me to be able to keep track 😅