World simulation(Stream<Event> events, World world) =>
events.IsComplete
? world
: simulation(applyEventToWorld(events.Head, world), events.Tail);
World applyEventToWorld(Event event, World world) =>
// .. create a new World using the immutable inputs
That takes the first event that arrives, transforms the World, then recursively calls itself with the remaining events and the transformed World. This is the most pure way of doing what you ask. Recursion is the best way to 'mutate', without using mutable structures.
However, there are real mutation constructs, like IORef [1] It will do actual in-place (atomic) mutation if you really want in-place updates. It requires the IO monad.
However, there are real mutation constructs, like IORef [1] It will do actual in-place (atomic) mutation if you really want in-place updates. It requires the IO monad.
[1] https://hackage.haskell.org/package/base-4.20.0.1/docs/Data-...