https://kotlinlang.org logo
#arrow
Title
# arrow
g

george.m

03/18/2024, 7:49 PM
I am trying to find an example of how I can perform Comprehensions with Λrrow, Paco has an example of what I want to achieve. Instead of this:
Copy code
fun calculateDoubles(calcParams: Params) =
    calcParams
            .let { params ->
                defrombulate(params.first, param.second)
                        .let { result ->
                            gaussianRoots(result)
                                    .let { grtts ->
                                        storeResult(params.first, params.second, result, grtts)
                                    }
                        }
            }
and do this instead:
Copy code
fun calculateDoubles(calcParams: Params) =
    // chained with let()
    doLet(
        { calcParams },
        { params -> defrombulate(params.first, param.second) },
        { params, result -> gaussianRoots(result) },
        { params, result, grtts -> storeResult(params.first, params.second, result, grtts) }
    )
Although in my code I have returns of types
Result
or
Either
. I have tried looking on the Arrow docs but couldn't find an example of what I am looking for? Could someone point me to some examples or documentation? But I may be mistaken, and Comprehensions is not the way I should go about this.
@pakoito ☝️
y

Youssef Shoaib [MOD]

03/18/2024, 8:01 PM
The way to do it in Arrow is to either do this:
Copy code
fun calculateDoubles(calcParams: Params) = either {
    val result = defrombulate(calcParams.first, calcParams.second).bind()
    val grtts = gaussianRoots(result).bind()
    storeResult(calcParams.first, calcParams.second, result, grtts)
}
Or it's even better if instead of returning
Either
and
Result
you instead use a
Raise<MyErrorType>
receiver:
Copy code
fun Raise<MyErrorType>.calculateDoubles(calcParams: Params) {
    val result = defrombulate(calcParams.first, calcParams.second)
    val grtts = gaussianRoots(result)
    return storeResult(calcParams.first, calcParams.second, result, grtts)
}
👀 1
g

george.m

03/18/2024, 8:09 PM
Ok, these examples don't look like chaining, more like imperative code, besides the
bind()
, where we're waiting for the result as a
val
then passing result in as an argument, where as in @pakoito’s examples the result is chained. and as mentioned, I currently receive a
Result
so I am `.fold()`'ing over the result and chaining manually and want to make that cleaner. I'll look for a `either`/`bind()` example
y

Youssef Shoaib [MOD]

03/18/2024, 8:10 PM
That's the point. There's no need for chaining over
Either
or
Result
.
bind
handles the unsuccessful case for you. It's like do-notation or for-comprehensions if you're familiar with those
g

george.m

03/18/2024, 8:11 PM
do-notation or for-comprehensions if you're familiar with those
I can't say I have had a lot of experience 😢
But effectively that is what I am after
y

Youssef Shoaib [MOD]

03/18/2024, 8:12 PM
g

george.m

03/18/2024, 8:14 PM
OK... I am going to give the `either`/`bind()` example a try... as I haven't thought about my error types yet... and then I may come back to look at the
Raise<*>
Thanks for the guidance 👍
k

Krisztian Balla

03/20/2024, 6:44 AM
you could also just flatMap over them, however for your use case you want to use Raise. (whether you do either+bind or Raise you need to know the Errors your code can result in, that is the whole point for eithers)
p

pakoito

03/25/2024, 5:29 PM
Bit of a week late and I’m with Youseff in this one
Suspend is used as a way of making declarative code look imperative
behind the scenes, the code behaves the same as if chained
including returning a value when it fails, same way a suspension can be cancelled or stopped from within and return Promise.reject or Job.failed
g

george.m

04/08/2024, 5:52 PM
I have been using the
either
comprehensions, which have worked nicely for me so far
Copy code
either { 
   val cool = doSomeThingCool().bind()
   val cooler = makeItCooler(cool).bind()
}.fold(
  ifRight = {},
  ifLeft = {},
)
Whilst I am here though, if I am catching a throwable in the
ifLeft
what is the recommendation to bubble that up to Crashlytics or similar?
p

pakoito

04/09/2024, 9:26 AM
at the top top top topmost the right should be Unit, right? So you recover the left with reporting to crashalytics in a Either.catch {}, and you don’t fold
👍 1
anything below that yeah, case-by-case as you need to return a value
log and return nullable with a tapLeft to side-effect to crashalytics
2 Views