Result keep got updated <https://github.com/Kotli...
# arrow
s
s
This would mean arrow can replace Either data type with Result ?
k
Arrow Either allows Left (Failure) to be any Type
I din't really understand why they choose to require
Failure
type to require a type argument. 🤔
Copy code
class Failure<T>(val exception: Throwable) : Result<T>()
instead of
Copy code
class Failure(val exception: Throwable) : Result<Nothing>()
s
But when you are using Result than it wouldn’t matter, if Failure is extending from Result<Nothing>. Also when using Failure, Success type T isn’t used, so that’s probably just boiler plate to support generic type for Success with sealed class.
But anyway, with plans to introduce Union Type, I think Either can be dropped easily.
In favor of Result I mean.
m
I'd personally still choose Either to Result in a heartbeat due to the typed left channel. Having to work with IO containers (e.g. reactor/rx) I can't imagine having to build anything without it. With result you'd have no more access to the monad transformer you'd normally get with Either. Having to always do a when clause all the time on every success is too painful to even imagine.
👍 1
s
But anyway, with plans to introduce Union Type, I think Either can be dropped easily.
@Satyam Agarwal That is actually not the case since
Union
has no bias. Meaning it has no
flatMap
or short-circuit behavior. Union types is support in the language to create ad-hoc
sealed class
definition without having to rely on wrappers. So you can do
Int | String
without having to define
sealed class IntOrString
with 2x
data class
that wraps
Int
or
String
.
Arrow Either allows Left (Failure) to be any Type
Like @kioba said
Result
cannot replace
Either
since it only models
Either<Throwable, A>
and not
Either<E, A>
.
Result<A>
is actually the equivalent of
Try<A>
, and is used inside the
suspend
(
Continuation
) machinery. However, I plan to add support for
result { }
into Arrow, currently also with an
@Experimental
flag. @mitch
With result you'd have no more access to the monad transformer you'd normally get with Either.
Are you using
EitherT
a lot? It's actually being deprecated instead of
either { }
with
suspend
. It's possible to replace
EitherT
with something simpler and more efficient tho based on what we now have in Arrow Core, but that would not be implemented generically with monad transformers but rather concretely with extensions. On the plus side that would be more efficient, and the resulting syntax would probably be a lot nicer. How are you using
EitherT
with RxJava today?
🤘🏼 1
🤘 3
m
Yeah I'm aware of the deprecation. We use Reactor, and we roll out a custom wrapper around
Mono<Either<L, R>>
and a bunch of homegrown extension functions. we considered arrow fx but decided not to as it was still heavily changing. Curious to see how would that look like when we replace its machinery with
either { }
?
👍 1
s
I would assume it would look very similar to what you currently have. If you're interested in making those utilities open-source, then I'd be very happy to help review and make some suggestions if needed 🙂
👍 1
m
Awesome, yeah I'm a bit curious if that's better contained in arrow-fx-reactor instead? If i were to check in these wrappers, I've been wondering if i should look into contributing there instead?
s
What is currently in Arrow Fx Reactor is all based on the effect typeclasses, higher kinded types etc and it was an abstraction over single-shot effects
suspend () -> A
rather than streaming effects. For example, there was no polymoprhic way to do
Observable.fromIterable
or any other constructor for
N
elements. Since we're now using KotlinX Coroutines as the underlying runtime for Arrow Fx Coroutines, we're also advising to use KotlinX Coroutines Reactor integration to integrate for example
parZip
or other concurrency operators provided in Arrow Fx Coroutines. However, there could still be a need to create an Arrow Fx Coroutines Reactor module, or Arrow Reactor. Some operators that come to mind:
Copy code
fun <A, B> Flux<A>.retry(schedule: Schedule<Throwable, B>): Flux<A> = ...
fun <A, B> Flux<A>.repeat(schedule: Schedule<A, B>): Flux<B> = ...
or
Copy code
fun <E, A, B> Flux<A>.mapEither(f: RestrictedEitherEffect<E, *>.(A) -> B): Flux<Either<E, B>> = map { a -> either.eager { f(a) } }

val res: Flux<Either<String, Int>> =
  Flux.fromIterable(listOf(1, 2, 3))
    .mapEither { i ->
      val x = 1.right().bind()
      "error".left().bind()
    }
That's why I was curious to know what kind of extensions you currently added to your project, and to see if could perhaps collaborate to turn it into a meaningful library for the whole community to enjoy 🙂 PS: I assume you're using Project Reactor since you're using Spring WebFlux? What is the reason for sticking to Project Reactor rather than using KotlinX Flow?I know Project Reactor (/RxJava) has a lot more functionality out of the box that I also frequently use. However, the plans for Arrow Fx Coroutines are to fill this gap for KotlinX Flow by providing extension for Flow of missing functional operators.