Expressing do block using only monadic bind syntax

code-translation, do-notation, haskell, monads, scope

Solution

Yes, all of them can be converted to bind syntax; in fact, they are converted internally by the compiler.

I hope this translation of your example gives you the hint:

main = readFile "foo.txt" >>= \f ->
       (print $ "prefix " ++ f) >>
       (print $ f ++ " postfix")

Problem

As far as I know, `do` blocks in Haskell are just some kind of syntactic sugar for monadic bind operators. For example, one could convert ``` main = do f <- readFile "foo.txt" print f print "Finished" ``` to ``` main = readFile "foo.txt" >>= print >> print "Finished" ``` Can all `do` blocks be converted to bind syntax? What about, for example, this block where `f` is used multiple times: ``` main = do f <- readFile "foo.txt" print $ "prefix " ++ f print $ f ++ " postfix" ``` Assuming we are in the IO monad, it is not possible to simply execute the `readFile` computation twice. How can this example (if possible at all) expressed using only bind syntax? I think using `Control.Monad` is no solution, because it internally uses `do` blocks. I think it it's possible to express this using arrows (using `&&&`) -- maybe this is a case where only arrows can be used as a generalization of monads? Note that this question is not about the special examples above but about the general case of the result of a computation being used multiple times in monadic expressions like `print`.

Original source