Polymorphic child modules

Let's say I want to render a todo list with various types of todos: singleton tasks, nested tasks, checklists, ... with each type having common & type-specific state/behaviour.

To model these, my mind goes to a separate state, view, and reducer for each type. Where I get stuck is how to express this polymorphism when I want to store an array of heterogeneous todos to render them all in a list. I'd need to maintain a state tree with different types of nodes, wrap the actions for the different types, and combine the appropriate reducers. I reached for a protocol, but quickly ran into the usual PAT issues when I make each todo's action and state an associated type.

Is there a pattern for handling this in TCA?

we have a similar use case, where one of our state is an enum with 2 cases who both have an associated value which is a substate (we don't push the same views depending on the case) :

enum MyState {
  case case1(SubState1)
  case case2(SubState2)
}

we then tried to create a reducer that would return Case1Reducer or Case2Reducer depending on the case we were in, but couldn't implement what we had in mind to the end. It kind of feels that we need to use a pullback method that takes a CasePath instead of a WritableKeyPath. But how could we handle the inout state that way ?

we could work around it by defining SubState1 and 2 as optional properties of our ParentState (not the best way to do it, but it works), but it wouldn't be possible in your case :/.

But we do have the same question as you, is there a pattern or what is the best way to manipulate and compose with these kind of states?

@pmaes, PointFree just tweeted about this scenario : https://twitter.com/pointfreeco/status/1324721577452253186

there is an example of what they have done, but it impacts the Reducer type, and let you use a Type that can act as a "wrapper" around key paths and CasePaths and let you compose with it.

So it seems that it is not possible today, but could be in the future with an update on the Reducer Type :slightly_smiling_face:.

Definitely feel free to copy that stuff into your project and give it a spin! We are using it a ton in a project right now and it's working great. We just want to spend a little more time with it before we push it into the library. :)

@mbrandonw thank you for your answer on twitter :wink:.

We will try that with our use case :slightly_smiling_face:.

I hope one day, CasePath and a standardized Lens approach will land on Swift Standard Library :slightly_smiling_face:.

1 Like