Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What to use instead of a main loop in Haskell?

Tags:

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?

like image 243
snow Avatar asked Jan 26 '12 08:01

snow


People also ask

Is there a for loop in Haskell?

Recursion is important to Haskell because unlike imperative languages, you do computations in Haskell by declaring what something is instead of declaring how you get it. That's why there are no while loops or for loops in Haskell and instead we many times have to use recursion to declare what something is.

How do you use loops in Haskell?

Someone told me that when you want to do loops in Haskell think of either recursion or list comprehensions. Not relevant to your question here, but suppose you want to add all the elements in a list. Of course you need to iterate over all the elements. Recursion will work, and so will using a list comprehension.


1 Answers

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.

like image 68
ehird Avatar answered Oct 02 '22 22:10

ehird