GHC Proposal: Top-level IO initialized bindings
Haskell Community [Unofficial]
June 29, 2026
github.com/ghc-proposals/ghc-proposals
Top-level IO initialized bindings (#766)
master ← brandonchinn178:top-level-io
opened 04:46AM - 29 Jun 26 UTC
brandonchinn178
+176 -0
This has been a long-standing discussion, as documented at the Top-level mutable state page in the Haskell Wiki. After discussion in Can NOINLINE fail to prevent inlining?, this is my attempt at the problem.
The core of my proposal is:
OPAQUEis better thanNOINLINEfor this idiom, but it’s not obvious that one should useOPAQUEoverNOINLINE- One must use
unsafePerformIO, but it’s not actually unsafe if one usesOPAQUE. You lose ordering guarantees with regard to other IO actions, but that’s no more unsafe thanhGetContents. foo :: %TopLevelIO (IORef Int); foo = newIORef 0is actually semantically sound and safe, provided the compiler respect the modifier
Discussion in the ATmosphere