Working with effect-dependent data

I’m working on porting a TypeScript project that was using a tree structure with unique IDs in each node. The ID generator was global and as such all functions that operate on the tree produce side effects. What are some good patterns for deal with this kind of effect-dependent data?

Similar, I’d like to try making a game at some point in the future and I’d like to randomize aspects of the game. This seems like a similar problem so hopefully any suggests you have about unique IDs will also be applicable to random numbers. :crossed_fingers:

Instead of explicitly threading a state through your code, I would suggest that monad transformers is a pretty standard way to handle this. You wrap whatever state you want in a Control.Monad.State monad and inside the body of your functions, you have access to that state via get, put or modify functions of said monad. At the top level of the program, you runState, pass the initial state in and get the final state back. Or evalState if you don’t care about the final state.

Or, if you feel really adventurous, extensible effects are all the rage these days. I find this blog post to be very helpful. And in PureScript land, I have been using purescript-run for the past several weeks. It is a very capable library.

With it, the side effects are modeled as pure data and you can interpret them effectfully in the real program or purely in the tests. And they are composable. I ported the example in that blog post to purescript-run and you may want to check it out here. It has pretty much everything: how to define your own effects, how to use them in the client code and how to interpret them effectfully and purely.

Of course, you can simply use predefined Run.State analogous to Control.Monad.State.

I’m not advocating one way or the other. The monad transformers and algebraic effects are both very capable. Your choice :grin:

3 Likes