I am trying to implement a trivial two-state state...
# getting-started
b
I am trying to implement a trivial two-state state machine (turnstile) using `fun`s to implement states. First problem was that
typealias
didn’t support a recursive definition so I couldn’t do:
Copy code
typealias State = (pushes: ReceiveChannel<Unit>, coins: ReceiveChannel<Unit>) -> State
So I had to resort to defining
State
as a
@FunctionalInterface
meh. With some liberal casts, this compiles but it fails at runtime (see comment above line 59): https://gist.github.com/Bill/b9cbfdb1d6fbba42258ee0a6fcee7240 Eschewing
fun
and defining the states as `object`s works but that seems like a lot of extra ceremony: https://gist.github.com/Bill/d5fa8c0290e49fccb90936745b29e86f Any ideas here?
d
I've had a lot of luck using sealed classes to implement a FSM. Have you tried using those?
If you're trying to integrate with coroutines that's kind of a different beast though.
b
I don’t think the parameter types matter in this case. I think I could eliminate `Channel`s and I’d face the same problems. Thanks for the sealed class tip @dalexander
yeah I could see using a sealed class to implement the set of states. That would be a better implementation of my OO example. I’ll try that for sure! but my question about using `fun`s still stands
d
Just trying to provide a bit of feedback. It's possible there's an example of implementing an FSM with coroutines in Kotlin, but I don't know enough about working with coroutines to help in that case. I can tell you the reason this line fails though:
var state = ::locked as State
the reason is a function is not part of state interface. Under the hood ::locked probably looks something like
Function2<ReceiveChannel, ReceiveChannel, State>
which is not a
State
. The only time Kotlin coerces function types to interfaces is when it's making calls to Java (which helps with Java 8 compatibility).
b
thanks @dalexander! btdubs I updated my non-functional (but working heh) example to use a
sealed
class instead of a
@FunctionalInterface
https://gist.github.com/Bill/d5fa8c0290e49fccb90936745b29e86f
d
Cool, the sealed class component mostly is useful when determining behavior based on what state the code is in, or determining if a state transition is legal, since it basically turns your FSM into a very fancy enum. 🙂
👍 1