What I'm trying to achieve in my personal project is an 'evaluator function', that should elect a valid strategy, without invoking that twice. Currently, my code is:
fun electStrategy() = listOf({ attemptStrategyA(x) }, { attemptStrategyB(x) })
.find{ it.invoke() == true } ?.invoke()
// where `attemptStrategyA(x)` and `attemptStrategyB(x)` return `T`
As you can see from the above, I need to first evaluate the strategies in a lazy fashion and then, when the predicate condition is met, I would like to get elected strategy value.
How can I do the above without having to evaluate such strategy twice and more elegantly?
CodePudding user response:
I think your example has a problem with its predicate. But assuming predicate()
is a function that returns true or false on a result of a strategy invocation, you could write it this way:
fun electStrategy() = sequenceOf({ attemptStrategyA(x) }, { attemptStrategyB(x) })
.map { it.invoke() }
.firstOrNull { predicate(it) }
Using sequenceOf
instead of listOf
makes the .map
operation lazy, which means the predicate will be evaluated on the result of a strategy before the next strategy is attempted.