Clark Gaebel cgaebel at uwaterloo.ca
Tue Dec 24 02:30:50 UTC 2013

```The way forever is implemented is a bit obtuse. It's mainly a hack to make
GHC's optimizer avoid space leaking no matter what the surrounding code is.

You can think of the implementation as just:

forever :: Monad m => m a -> m b
forever act = do
act
forever act

which is pretty much what you'd do in an imperative language, so it's not
that crazy.

You can see the similarity if you replace the do notation with manual binds
and rename 'act' to 'a':

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

Again, the knot tying stuff is just to prevent a space leak in certain
optimization scenarios.

On Mon, Dec 23, 2013 at 9:02 PM, Eduardo Sato <eduardo.sato at gmail.com>wrote:

> Hello, guys.
>
> Recently I came across the definition of the function 'forever' on hoogle. I am intrigued that it works.
>
> The recursive definition does make sense to me in a mathematical way, but I can't figure out how it works under the hood in terms of thunks.
>
> To tell you the truth, I don't know how laziness works in general in haskell.
>
> Can someone help me understand how it works in this example, and give some pointers to materials on the subject?
>
> The "tying the knot" article on the wiki is pretty mind bending too.
>
> -- | @'forever' act@ repeats the action infinitely.
>
> forever     :: (Monad m) => m a -> m b
>
> {-# INLINE forever #-}forever a   = let a' = a >> a' in a'
>
> --
>
> Eduardo Sato
>
>
> _______________________________________________
>
>

--
Clark.

Key ID     : 0x78099922
Fingerprint: B292 493C 51AE F3AB D016  DD04 E5E3 C36F 5534 F907
-------------- next part --------------
An HTML attachment was scrubbed...