Well I don't think that fits at all. In Zig, an Io instance is an interface, passed as a parameter. You can draw some connections between what Zig is doing and what Haskell is doing but it's not a monad. It's plain old interfaces and parameters, just like Allocator.
Passing an interface as a parameter is a monad. (Io -> _) is an instance of Monad in Haskell.
Haskell just has syntax to make using (any) monad much nicer. In this case, it let's you elide the `Io` parameter in the syntax if you are just going to be passing the same Io to a bunch of other functions. But it still is there.
Couldn't have said it better myself. But IIUC Andrew stated that its not a monad because it does not build up a computation and then run. Rather, its as if every function runs a `runIO#` or `runReader` every time the io parameter is used.
Is it necessary that a monad "builds up a computation and then runs"? In fact it's very hard for a monad to do that because the type of bind is
so you can really only make progress if you first build a bit (`m a`), then run it (to get `a`) then build the next bit (applying `a` to `a -> m b`), then run that. So "building" and "running" must necessarily be interleaved. It's an odd myth that "Haskell's IO purely builds an impure computation to run".
Are you saying "monad" is a synonym of "interface"?
Not a synonym, but `Monad` is one of the commonly used interfaces in Haskell (not the only one).
OK I think I understand now, thank you. My takeaways:
1. Yes, Zig is doing basically the same thing as Haskell
2. No, it's not a monad in Zig because it's an imperative language.
It still is a monad. It's just Zig doesn't have language support for monads, so it's less ergonomic.
Just as modular addition over ints in Zig forms a group, even if Zig has no notion of groups. It's just a property of the construct.
Laziness has nothing to do with it.
What that means practically for Zig, I'm unsure.
Monads do not need to build up a computation. The identity functor is a monad.
And for comparison, here's Haskell's (or rather Bluefin's) equivalent of Zig's `Io` parameter:
https://hackage-content.haskell.org/package/bluefin/docs/Blu...