简体   繁体   中英

How does forever monad work?

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?

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 ma 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 ma 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.

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.

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