0

I want to write a loop in haskell using monads but I am having a hard time understanding the concept.

Could someone provide me with one simple example of a while loop while some conditions is satisfied that involves IO action? I don't want an abstract example but a real concrete one that works.

5
  • Does this question help? Commented Feb 13, 2017 at 21:37
  • 1
    Possible duplicate of While loop in Haskell with a condition Commented Feb 13, 2017 at 21:39
  • I already saw that but is there one even simpler where I can easily tell what the program is trying to compute immediately. Commented Feb 13, 2017 at 21:41
  • 5
    Do you have an example of an imperative while loop that you can't convert? Commented Feb 13, 2017 at 21:51
  • @Lee Say something very simple like if some condition is satisfied, you keep printing "satisfied" while updating the condition. I don't want a straightforward recursion but something using monads. Commented Feb 13, 2017 at 22:19

1 Answer 1

8

Below there's a horrible example. You have been warned.

Consider the pseudocode:

var x = 23
while (x != 0) {
   print "x not yet 0, enter an adjustment"
   x = x + read()
}
print "x reached 0! Exiting"

Here's its piece-by-piece translation in Haskell, using an imperative style as much as possible.

import Data.IORef

main :: IO ()
main = do
   x <- newIORef (23 :: Int)
   let loop = do
          v <- readIORef x
          if v == 0
          then return ()
          else do
             putStrLn "x not yet 0, enter an adjustment"
             a <- readLn
             writeIORef x (v+a)
             loop
   loop
   putStrLn "x reached 0! Exiting"

The above is indeed horrible Haskell. It simulates the while loop using the recursively-defined loop, which is not too bad. But it uses IO everywhere, including for mimicking imperative-style mutable variables.

A better approach could be to remove those IORefs.

main = do
   let loop 0 = return ()
       loop v = do
          putStrLn "x not yet 0, enter an adjustment"
          a <- readLn
          loop (v+a)
   loop 23
   putStrLn "x reached 0! Exiting"

Not elegant code by any stretch, but at least the "while guard" now does not do unnecessary IO.

Usually, Haskell programmers strive hard to separate pure computation from IO as much as possible. This is because it often leads to better, simpler and less error-prone code.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.