iex
05/02/2020, 5:56 PMfun foo(start: Foo): Result<List<MyRes>> {
val list: MutableList<MyRes> = mutableListOf()
var bar = start
while (bar < condition) {
when (val result = retrieveSomething(bar)) {
is Success -> list.addAll(result.success)
is Failure -> return Failure(Throwable("Error: ${result.error}"))
}
bar = bar.next()
}
return Success(list)
}
Dominaezzz
05/02/2020, 6:01 PMgenerateSequence
but that failure case is quite troublesome.Dominaezzz
05/02/2020, 6:04 PMgenerateSequence(start) { it.next() }
.takeWhile { it < condition }
.map { retrieveSomething(it) }
.flatMap {
when (it) {
is Success -> it.success
is Failure -> throw Throwable("Error: ${it.error}")
}
}
.toList() // Catch exception here and wrap in Failure.
iex
05/02/2020, 6:07 PMiex
05/02/2020, 6:08 PMSaku Ytti
05/02/2020, 6:09 PMSaku Ytti
05/02/2020, 6:09 PMiex
05/02/2020, 6:10 PMiex
05/02/2020, 6:12 PMDominaezzz
05/02/2020, 6:12 PMgenerateSequence(start) { it.next() }
.takeWhile { it < condition }
.map { retrieveSomething(it) }
.asIterable()
.flatMap {
when (it) {
is Success -> it.success
is Failure -> return Failure(Throwable("Error: ${it.error}"))
}
}
iex
05/02/2020, 6:13 PMiex
05/02/2020, 6:13 PMiex
05/02/2020, 6:13 PMDominaezzz
05/02/2020, 6:14 PMiex
05/02/2020, 6:14 PMiex
05/02/2020, 6:15 PMDominaezzz
05/02/2020, 6:15 PMreturn@YourFunctionsName
.iex
05/02/2020, 6:16 PMiex
05/02/2020, 6:20 PM@YourFunctionsName
. I just had to add a `
.let { Success(it) }
at the endiex
05/02/2020, 6:21 PMiex
05/02/2020, 6:22 PM@YourFunctionsName
is returning from the function or only flatmap though. Will have to confirm that. It also compiles with it)Dominaezzz
05/02/2020, 6:25 PMList<T>
to flatmap and we're not.Derek Peirce
05/02/2020, 7:18 PMtailrec fun foo(start: Foo, prior: List<MyRes> = mutableListOf()): Result<List<MyRes>> {
return if (start < condition) {
when (val result = retrieveSomething(start)) {
is Result.Success -> foo(start.next(), prior.apply { addAll(result.success) })
is Result.Failure -> Failure(Throwable("Error: ${result.error}"))
}
} else {
Result.Success(prior)
}
}
Jakub Pi
05/03/2020, 1:02 AMfun <A> sequence(xs: List<Result<A>>): Result<List<A>>
This should capture the short circuiting and also replace the when expression. There's no reason to map the failure, you are only losing type information if you do it that way.
I'm also curious if you are using kotlin.Result
since the implementation doesn't currently like for it to be used as a return value. BTW, as an alternative to Result, arrow's Either has the short circuiting semantics that you want (including a sequence operation already defined), but learning how to actually use arrow properly has been challenging at least for me.
I'll also mention the condition is a bit suspect. I realize the code is intentionally obfuscated, but remember to avoid referencing anything outside the function to keep it pure.