{-# LANGUAGE TemplateHaskell #-} module Main where import Data.IORef (IORef, atomicModifyIORef', newIORef) import InitOnce globalRef :: IORef Int globalRef = $$(once [|| newIORef 0 ||]) -- wrong :: Typeable a => IORef [a] -- does not typecheck: no instance Typeable a -- wrong = $$(once [|| newIORef [] ||]) {-# NOINLINE foo #-} foo :: IO String foo = atomicModifyIORef' globalRef (\i -> (i + 1, show i)) main :: IO () main = do putStrLn =<< foo -- 0 putStrLn =<< foo -- 1