Question regarding unsafePerformIO and ForeignPtr

Using some formatting from nometa’s question and some paraphrasing:

…if by “cached representation” you mean the the stored result, by way of Haskell’s non-strict semantics: maybe. It will depend on the underlying implementation e.g. there are currently two for GHC: single and multi-threaded.

By disguising the use of I/O, you’re telling the Haskell implementation that the result of calling showData is just another regular Haskell expression (i.e. no observable effects), so it’s free to treat that result like any other Haskell expression:

  • if it is a regular Haskell expression, there should be no problems with running it more than once (apart from the extra time required) - the implementation deciding that’s it’s cheaper to recompute:

  • alternately, if there are two or more identical calls of showData in your program:

    ( ... (showData d) ... (showData d) ... )
    

    there ought to be no problems with the Haskell implementation changing that into:

    let x = showData d in
    ( ... x ... x ... )
    

Back to the original question:

If your programs are that dependent on such details, you should use unit testing as an “early-warning system”, to lessen the chances of surprises happening in your programs.