4 ms·
No, it's more that getChar :: IO Char does not need to know anything about "monads"—it only depends on having some IO type for "IO actions" or "IO procedures" o
by tikhonj 8y ago
No, it's more that getChar :: IO Char does not need to know anything about "monads"—it only depends on having some IO type for "IO actions" or "IO procedures" or whatever you want to call them. Combine the concrete IO type with a few built-in library functions for building larger IO actions out of smaller ones and you have a perfectly good (albeit unextensible) effect system without every saying the word "monad".
Interestingly, the programming experience with this is going to be pretty much the same as using a language with promises. It would be like working in JavaScript with no blocking IO, but with some abstraction and syntax sugar to make it less powerful.
Or, more pointedly, it would be like working in OCaml. OCaml might not "need" monads, but all serious OCaml is full of monads anyway, at least depending on LWT or Asyc for concurrency.
- xfer 8y ago> Combine the concrete IO type Why does it need that concrete type (taking one world and producing another)? Why can't i just have it's concrete type be Char? (obviously you would implement with some unsafe inside). But does referential transparency still hold?
- JadeNB 8y agoWell, as you said in your earlier post, referential transparency can’t hold unless you only ever want to `get` one `Char`; that’s the definition.
- tikhonj 8y agoHaskell doesn't "need" an IO type—it wants one. The IO type gives us a language-level way to separate code that has side-effects from code that doesn't. It's a powerful tool to help manage complexity in our programs. One of the advantages of keeping IO in an explicit IO type is that code that isn't in IO becomes easier to refactor. This is what people mean by referential transparency: since I know that a `Char` cannot implicitly depend on the state of the rest of the program, I am always free to move it around, put it in a variable or replace it with an equivalent expression without changing the meaning of the program. You would not get this with getChar :: Char because two getChars could give you different results, so moving them around or reordering them would change the semantics of your program.
- marcosdumay 8y ago> it only depends on having some IO type for "IO actions" or "IO procedures" or whatever you want to call them. It needs some IO type that you can put stuff in it; when that stuff is functions you need some way from passing previous results as arguments of the next ones; also, you need some way to compose that stuff in a defined order. You do those, and you have a monad. Other languages do not work without monads, they just get a single IO monad that everything is implicitly inside. Their programmers can afford not to say "monad" because they only get one to choose, and can't choose not to take it either.