|
|
|
|
|
by chriswarbo
2956 days ago
|
|
It's easy to split hairs about what "being functional" means, but the way that Haskell implements IO is certainly a byproduct of this. In particular, my preferred mental model of Haskell doesn't include "functions that write to file handles"; but rather, these would be pure functions which return IO "actions". This distinction is often inconsequential, but this case seems to rely on how we combine those "actions" together (which, due to laziness, may happen far away from where/when the functions are called; see 'lazy IO'). For sequential IO we can combine things with Applicative and Monad, which gives us a definite order, but using these in a concurrent setting would cause too much synchronisation and determinism to be useful. I've not done enough concurrent Haskell to know how the various alternatives stack up; although I did play with Arrow many years ago, before it fell out of favour (seemingly for Profunctors?). |
|
Monadic I/O on its own doesn't make any guarantees, or impose any requirements, about locking external resources. If stdout is locked (from within the monad, or not), then that's the state the world arrives in for your effect. If not, then it's not. They are orthogonal concerns.