https://kotlinlang.org logo
Title
j

João Gabriel Zó

03/17/2023, 6:00 PM
I have 2 functions which return Results.
functionOne: Result<Something>
functionTwo: Result<Unit>
I’ll only call functionTwo if the first one returns a Success, and return a
Result<Something>
in case both of them return a Success. What’s the best way to do it using std lib? I thought the nested folds and maps and ifs turned out a bit ugly
f1().map { something ->
  f2().map { it }
  something
}
will it work?
e

Emil Kantis

03/17/2023, 6:16 PM
no, result of line 2 is always ignored
f1().mapCatching { t ->
      f2().onFailure { throw it}
      t
   }
might be easiest
j

João Gabriel Zó

03/17/2023, 6:30 PM
alright, thanks!
e

ephemient

03/18/2023, 6:09 AM
if you were to write it without
Result
, it would look like
run {
    val x = f1()
    f2()
    x
}
(or something simpler like
f1().also { f2() }
)
with
Result
, you just translate that to include monadic bind, e.g. `.getOrThrow()`:
runCatching {
    val x = f1().getOrThrow()
    f2().getOrThrow()
    x
}
(or
runCatching { f1().getOrThrow().also { f2().getOrThrow() } }
)
if you were using #arrow's Either instead of kotlin.Result then
either {
    val x = f1().bind()
    f2().bind()
    x
}
(or the short version) is the intended usage: https://arrow-kt.io/docs/patterns/monad_comprehensions/
p

pakoito

03/20/2023, 10:04 AM
one().flatMap { it -> two.map { it } }
which is what
flatTap
does in Arrow