Search code examples
haskelltypesmonadstype-signature

Haskell `forever` type signature


In Haskell why is type-signature of forever

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

Specifically why isn't it just :: Monad m => m a -> m a? Surely the type of monad we are acting upon doesn't change half way through forever?

A function such as:

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

seems to work exactly the same.


Solution

  • The type signature of forever is crafted to suggest that its result runs forever. Specifically, there is no way to write an action of type m b (polymorphic in its return value) that terminates and yields a non-bottom value. An alternative way to suggest the same thing would be forever' :: m a -> m Void.

    Another answer is to just say that this is the most general type available for the function as it's defined, so that's the one it was given.

    Prelude> let forever m = let x = m >> x in x
    Prelude> :t forever
    forever :: Monad m => m a -> m b
    

    These days, it probably should be defined differently:

    forever :: Applicative f => f a -> f b
    forever a = let x = a *> x in x