[Haskell-cafe] One-shot? (was: Global variables and stuff)

Judah Jacobson judah.jacobson at gmail.com
Thu Nov 11 13:56:22 EST 2004

On Thu, 11 Nov 2004 12:27:17 +0000, Ben Rudiak-Gould
<benjamin.rudiak-gould at cl.cam.ac.uk> wrote:
> On the other hand, these are perfectly safe:
>     once' :: IO a -> IO (IO a)
>     oncePerString :: String -> IO a -> IO a
>     oncePerType   :: Typeable a => IO a -> IO a
> once' seems virtually useless unless you have top-level <-, but the
> other two don't need it. I'm not sure which would be preferable. I lean
> toward oncePerString as more flexible and predictable, though it
> requires a certain discipline on the part of its users.

Reflecting on the matter, I don't think that oncePerString is
type-safe.  For example, it allows us to create the following:

ref :: IO (IORef a)
ref = oncePerString "foo" (newIORef undefined)

Here's an example in which we subvert the type system (and probably
crash the program) by writing a String and reading an Int from the
same IORef:

    ref >>= writeIORef ("foo")
    (x :: Int) <- ref >>= readIORef 
    print x

This is similar to the reason for ML's value monomorphism restriction.
 In contrast, oncePerType
preserves monomorphism nicely, since all instances of Typeable are monomorphic.

Thoughts?  Am I missing something?

More information about the Haskell-Cafe mailing list