A Haskell program executes the IO action at `Main.main`, which must have type `IO ()`.
`putStrLn :: String -> IO ()` is a pure function - if you give it the same input, it always the same IO action as a result.
I personally don't use functional languages because I find them too difficult given the needs and interests I have. I think about computations sequentially most of the time.
int ret = doStepOne();
if (ret == RESULT_OK) {
ret = doStepTwo();
}
if (ret == RESULT_OK) {
ret = doStepThree();
}
return ret;
would just be doStepOne() >>= doStepTwo() >>= doStepThree()
in a language with support for monads.This is also true for other things in other paradigms, such as async functions in javascript.
This is a good thing, however. In imperative programming, you have invisible temporal coupling. In pure-FP you have the same coupling, but it's exposed.