Isn't it just the monomorphism restriction at work? This works fine: > f () = do > a <- get_unique > putStr (showInt a "\n") > b <- get_unique > putStr (showInt b "\n") > c <- get_unique > putStr (showInt c "\n") > > > get_unique :: (?global_counter :: IORef Int) => IO Int > get_unique = readIORef ?global_counter J.A.