haskelllazy-evaluation

When forcing of strict evoluation is required with monads?


Considering the Haskell code:

do  -- it's IO !!!
  ...
  !x <- someFunction
  ... usage of x

how useful is ! here? It's a result of monadic (it's IO !) evaluation, so my questions are:

  1. if x is a primitive type like UTCTime (getCurrentTime for example), Int, Bool - does ! make sense?

  2. if x has "head" like String, Map k v, some record maybe? Then x can be lazy? How lazy? Does it mean that when I will use x later then real IO happens?

  3. Does IO monad have some more specific behavior in this context? Like little bit more strict than other (more "pure") monads?

By default I/O is lazy, then how does Haskell know when to call it immediately (passing through this expression) or when to substitute it with a thunk? By type of x? Something like: GHC has a list of primitive types and everything outside the list is substituted?

Any explanations are appreciated.


Solution

  • Unfortunately, there simply isn't any possible blanket answer. In general, you must know the implementation of someFunction -- and details about how x is used -- to decide whether forcing x is a good idea.

    Some commentary:


    * Okay, okay, there are a few exceptions, like readFile and getContents, all of which use unsafeInterleaveIO somewhere in their implementation. But this is not the normal situation.