4 ms·
I thought Monads were needed for IO to make sure IO operations happened in the correct order?
by ourlordcaffeine 7y ago
I thought Monads were needed for IO to make sure IO operations happened in the correct order?
- theaeolist 7y agoYes, this is the correct answer. For everything else you don't need monads. Monads impose an evaluation order, which Haskell by default does not have, since it is lazy.
- gmfawcett 7y agoMonads do not impose an evaluation order in Haskell. Monads let you thread state between computations, but that state may be lazily evaluated out-of-order. The belief that monads sequence IO operations is why new Haskell programmers have difficulty writing functions like "open file, read file contents, close file, and return contents". They assume the contents will be read before the file closes, and not when the contents are lazily evaluated up the call chain (leading to a "can't read closed file" error).
- deleted 7y ago[deleted]
- goto11 7y agoNo, you can force operations to execute in linear order without the use of monads, as long as one operation depends on the output of the previous. But you have to be careful not to reuse values. Imagine if the IO operations took an explicit world parameter instead of using a monad: main :: World -> World main world1 = let world2 = putStrLn world1 "Hello, what's your name?" let (world3, name) <- getLine world2 let world4 = putStrLn world3 ("Hey " ++ name ++ ", you rock!") in world4 The IO operations would be executed in the expected order due to the dependency of the "world" output of the previous operation. Monads not necessary. But if you accidentally used world2 twice then you would split the universe into two timelines. A monad can avoid this issue by hiding the world parameter and passing it on behind the scenes.
- sullyj3 7y agowhat actual concrete, real world, non sci-fi sounding problem does "splitting the timelines" represent?
- gmfawcett 7y agoA less poetic way of stating it: if you re-use an already-used world state, you are violating a logical constraint of the system. No timelines will be violated, you just have an invalid program. World states are supposed to consumed once only: they are "linearly typed" in fancy language. But Haskell cannot directly enforce the linear-type constraint on world states, so in theory these states could be used more than once. Fortunately, the IO monad encapsulates (hides) the states, so that you can't make this mistake in your application code -- you can't reuse what you can't access. World-states in Haskell aren't first-class values. They aren't actual objects that are being passed around during the execution of the program. They are more like tokens that exist during type checking, but are erased when the program is compiled or interpreted. Another way of phrasing it is that Haskell interpreters/compilers have specialized support for the IO monad: during type checking, it acts as if these states exist, but they have no operational meaning in the executed program.
- sullyj3 7y ago> you are violating a logical constraint of the system I'm looking for something even a little more concrete than this. Why would the program be invalid? Can you give an example of what would happen if we just went ahead and accessed a worldstate a second time, logical constraints be damned?