I have functions that represent steps in a process. Each function also knows the next step, if there is one. I'd like to be able to do something like:
fun fooStep() : Step? {
... do something ...
return ::barStep // the next step is barStep
}
These functions are called from a central dispatching function, which contains code a bit like this:
var step = startStep
while (step != null) {
step = step()
}
Note that the logic in a particular step also determines the next step, if there even is one.
I thought I could define Step
as:
typealias Step = () -> Step?
So a Step
is a function that returns another Step
, or null. However, this fails to compile with:
Kotlin: Recursive type alias in expansion: Step
I can work around this by wrapping the function in an object. eg:
data class StepWrapper(val step: () -> StepWrapper?)
and changing my function signatures accordingly.
Unfortunately, this means that I cannot just use function literals (eg: ::barStep
), but instead have to wrap them in a StepWrapper
:
fun fooStep() : StepWrapper? {
... do something ...
return StepWrapper(::barStep)
}
(I also have to change my dispatch loop, accordingly.)
I'd like to avoid the need to create these wrapper objects, if possible. Is there any way to do this in Kotlin?
Map<Condition, Step>
approach over theStepWrapper
approach described in the question? – Kaufmantypealias
, given that it explicitly points out recursive types as being a problem. – Kaufmandata class Node(val step: () -> Unit, val nextNode: Node?) fun step1(): Unit { println("step 1") } fun step2(): Unit { println("step 2") } val node2 : Node = Node(::step2, null) val node1 : Node = Node(::step1, node2) var curNode: Node? = node1 while (curNode != null) { curNode.step.invoke() curNode = curNode.nextNode }
If a function can conditionally return more than one step then the Map is needed. – Cursory