4 ms·
Not quite ELI5, but Haskell tries to make IO pure by essentially representing all side-effecting programs as data and separating evaluation from execution. If
by chousuke 11y ago
Not quite ELI5, but Haskell tries to make IO pure by essentially representing all side-effecting programs as data and separating evaluation from execution.
If you say, for example:
x = print "Foo"
then the value of x is a program that prints "Foo" when executed and in
y = x >> x
the value of y is a program that prints "Foo" twice.
The language runtime essentially executes the value of "main" (which may be lazily evaluated).
Where monads come into play is the composition of such programs, especially when a program may produce output that needs to be fed to another program. The "bind" function does that, and the Monad typeclass abstracts the pattern so that you're not limited to just sequential programs; for example, promises (asynchronously executed programs) are monadic as well.
- drostie 11y agoI have to comment to specifically highlight this comment above. You can easily understand monadic I/O when you understand chousuke's comment; until you understand that comment you will have trouble understanding how Haskell does I/O. So to say it again in slightly different words: when you are writing Haskell, your job is to generate `main :: IO ()` (if you have never read Haskell type annotations, that's short for "a thing named main which is a program which produces nothing important." To do so, you have a lot of building blocks, like `getLine :: IO String` (a thing named getLine which is a program which produces a String), `putStrLn :: String -> IO ()` (a function named putStrLn which takes a String as input and produces a program which produces nothing important). You also have functions which combine these together, like `(>>=) :: IO x -> (x -> IO y) -> IO y` (an operator named >>= which takes, on the left, a program which produces an x, and, on the right, a function which turns an x into a program which produces a y -- the operator then giving you a program which produces a y.) So one example is: main :: IO () main = getLine >>= hello where hello :: String -> IO () hello name = putStrLn ("Hello, " ++ name ++ "!") This is a program which prompts the user for a line (like, say, `Chris`), wraps it in some text, and prints that text out. The Haskell compiler just writes `main` to disk as the executable. The compiler does not "run" any of these programs; that happens when you run the executable which Haskell makes for you. It is called by this scary word "monad" because that describes two things you can do with programs, one of which is this fundamental `>>=` operator.