Hello everyone, I’m trying to get my hands dirty w...
# arrow
p
Hello everyone, I’m trying to get my hands dirty with arrow + project reactor. I have the following code snippet which does not work:
Copy code
import arrow.core.Either
import arrow.core.left
import arrow.core.right
import reactor.core.publisher.Mono

fun doSomething(): Mono<Either<String, Boolean>> = Mono.just(1).flatMap { listingId ->
    handle(listingId)
}

fun handle(x: Int): Either<String, Mono<Boolean>> =
    if (x == 1) Mono.just(true).right()
    else "something else".left()
Basically I return either a mono of some value or a default value which is not a mono (but could be if it makes things easier). In
applyforFinancing
I want to return the result of
::handle
, but that gives me:
Copy code
Type mismatch.
Required:
Either<String, Mono<Boolean>>
Found:
Mono<(???..???)>
How could one achieve that? Basically I somehow have to transform an
Either<Mono<…>, Mono<…>
to
Mono<Either<…,…>
Thanks in advance!
My solution looks like this:
Copy code
import arrow.core.Either
import arrow.core.left
import arrow.core.right
import reactor.core.publisher.Mono

fun applyForFinancing(): Mono<Either<String, Boolean>> = serviceCall2().flatMap { listing ->
  handle(listing)
}

fun handle(x: Int): Mono<Either<String, Boolean>> =
    if (x == 1) serviceCall1().flatMap { Mono.just(it.right()) }
    else Mono.just("something else".left())

fun serviceCall1() = Mono.just(true)
fun serviceCall2() = Mono.just(1)
Any feedback is appreciated, thanks!
c
There isn’t an interop between arrow and project reactor that is built into arrow from what I understand
I currently have one service that is using WebFlux / Project reactor and I’d really like to write some kind of adapter that allows you to just use arrow as I am not a fan of reactor in general, but would still like to benefit from the asynchronous handling of requests.
p
Yeah I feel you. We might try out webflux with coroutines soon and I'm looking forward to it
c
that got me in production right off the bat
all results by default need to be under 256kb
p
Yeah, we had the same 😁
Thank you anyways!
s
There are a couple approaches you could take here. You potentially keep your codebase in
suspend
and only wrap in
mono { }
from KotlinX Coroutines Reactor integration to wrap it back into the Project Reactor runtime.
Copy code
suspend fun applyForFinancing(): Either<String, Boolean> {
  val x = serviceCall2().await()
  handle(x)
}

// Domain in suspend
suspend fun handle(int: x): Either<String, Boolean> {
  if(x == 1) serviceCall1().await().right()
  else "something else".left()
}

// Library that returns Mono
fun serviceCall1() = Mono.just(true)
fun serviceCall2() = Mono.just(1)
🤘 2
If at some edge you need to convert back to
Mono
you can just wrap in
mono { }
from KotlinX Coroutines Reactor
p
Thank you for the input Simon! Right now we’re unfortunately not making use of suspend/coroutines - just using reactor for now. 🙂
But your example shows why I should bring that topic back to the table. 😉