Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does forever monad work?

Tags:

haskell

How does forever monad work?

forever :: (Monad m) => m a -> m b
forever a = a >> forever a

If I write

main = forever $ putStrLn "SAD, I DON'T UNDERSTAND!"

forever gets IO (), this isn't function, how can forever repeatedly call putStrLn?

like image 381
dev1223 Avatar asked Jun 04 '14 16:06

dev1223


2 Answers

From the definition of forever function, you can see that it is a standard recursive function.

forever :: (Monad m) => m a -> m b
forever a = a >> forever a

There is no magic going on there. forever is just a recursive function. In your particular case, this is a non terminating one. But whether it becomes a terminating or non terminating depends on how the Monad is defined for that type.

Inspect the type of >>, we get:

λ> :t (>>)
(>>) :: Monad m => m a -> m b -> m b

From that you can observe the input m a is just ignored. Another way to think about that is that >> function just performs the side effect of the first parameter passed to it. In your case the m a will correspond to IO () since that is the type of putStrLn.

Since IO forms a Monad, forever function can also act on IO related functions.

like image 155
Sibi Avatar answered Sep 22 '22 22:09

Sibi


The distinction to make is that putStrLn "SAD, I DON'T UNDERSTAND!" is an action, not just a value. It repeatedly executes that action. Whenever something of type IO a is evaluated, it executes its internal actions and then returns something of type a wrapped in the IO context. It doesn't have to take a parameter for the action to do something. For example, look at the getCurrentTime function from the time package. It just has type IO UTCTime, but if you call it several times you'll get different values back, even though it takes no parameters.

like image 27
bheklilr Avatar answered Sep 23 '22 22:09

bheklilr