简体   繁体   中英

What to use instead of a main loop in Haskell?

I need a loop for main in Haskell. I've tried this:

main :: IO ()
main =
  do
    putStrLn "do something"
    main

Is the above code the correct approach to take? Will this infinite recursion cause an overflow?

This is fine; no stack overflow will occur. Stack overflows in Haskell (and, indeed, any non-strict language) are different to those in other languages; they arise from accumulating large values without ever evaluating them, but you're not accumulating anything here; just sequencing an infinite chain of actions. You can think of it like this: Once the line is printed, the action is discarded, and control passes straight onto main ; nothing is kept on the stack because there's nothing that has to be returned to.

It's the same reason you can iterate through an infinite list without running out of memory: as the program goes further down the list, previous list cells are reclaimed by the garbage collector as they're no longer required. In this case, the previous sequencings are reclaimed, as there's no reason to keep around an action you've already performed.

That said, a nicer way to write this particular example is:

import Control.Monad

main :: IO ()
main = forever $ putStrLn "do something"

Of course, this won't work if your loop is ever intended to terminate. forever is itself implemented with recursion, so there's no benefit other than readability to doing this.

What you observe is the result of "tail call elimination / optimization", which is nothing special to Haskell. See eg http://en.wikipedia.org/wiki/Tail_call

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM