
Graham Klyne wrote:
Wouldn't it be easier to simply define "once" as a common Haskell library function?
Depends on the type and the expected semantics. As Adrian Hey already pointed out, (once :: IO a -> IO a) with the obvious semantics is never going to be safe, because it's just not the case that x = once (newIORef ()) y = x has the same intended meaning as x = once (newIORef ()) y = once (newIORef ()) No amount of compiler-specific magic is going to fix this. 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. In any case there would need to be support for different scopes: perProcess :: String -> IO a -> IO a perThread :: String -> IO a -> IO a perMachine :: String -> IO a -> IO a I suppose you could add perType :: Typeable a => IO a -> IO a with the stipulation that types in different processes are distinct (which seems like the only safe assumption). -- Ben