I think you are right... The only safe operation I can see for a one-time init is type IO (). All results have to be returned via side effects. Hence with my named-MVar proposal the first execution of the init function initialises certain named-MVars, and subsequent executions do nothing at all. The functions in the library would use the names-MVars directly. Therefore the once function in the NamedSem library is: once :: IO () -> IO () Keean. Judah Jacobson wrote:
On Thu, 11 Nov 2004 12:27:17 +0000, Ben Rudiak-Gould
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:
do 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? -Judah _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe