{
"$type": "site.standard.document",
"bskyPostRef": {
"cid": "bafyreicilmmnwkgm3gdpd2bhtacpqmka4j34cmxmv3ptawuhjg2u7s2a7u",
"uri": "at://did:plc:pi6woz4d47bkuws673w2il2r/app.bsky.feed.post/3mmsdw6rvaxi2"
},
"path": "/t/why-no-exposed-nulladdr-literal/14157#post_1",
"publishedAt": "2026-05-26T23:47:51.000Z",
"site": "https://discourse.haskell.org",
"tags": [
"compiler/GHC/Types/Literal.hs"
],
"textContent": "Suppose that, switching on `-XDataKinds -XGADTSyntax -XKindSignatures -XMagicHash -XUnliftedNewtypes` and importing the relevant definitions from `GHC.Exts`, one creates the newtype\n\n\n newtype MyAddr# :: TYPE AddrRep where\n WrapAddr# :: Addr# -> MyAddr#\n\n\n(perhaps because they wish to signal interaction with a particular, trusted subset of foreign code—I think this is not a wholly unreasonable thing to do). Then they might like to declare something along the lines of\n\n\n myNullAddr# :: MyAddr#\n myNullAddr# = WrapAddr# nullAddr#\n\n\nbut this is of course disallowed, being an unlifted top-level binding. Fair enough!\n\nThe next best thing (actually, the ostensibly better thing, seeing as GHC already internally seems to treat `nullAddr#` as a _literal_ —cf. `LitNullAddr` defined in compiler/GHC/Types/Literal.hs, but I am admittedly not very familiar with the GHC codebase) would be to be turn on `-XPatternSynonyms` and write\n\n\n pattern MyNullAddr# :: MyAddr#\n pattern MyNullAddr# = WrapAddr# _\n\n\nwhere the hole is filled by some literal coinciding in value with `nullAddr#`. Indeed, were such a literal available, I don’t see why it wouldn’t make sense to deprecate the current `nullAddr#` in its favor, much like the old `void#` was deprecated in favor of `(# #)`.\n\nUnfortunately, such a literal does not seem to be available, neither via `-XExtendedLiterals` nor by using `-XTemplateHaskell` to splice some constructor of `Lit` from `Language.Haskell.TH`. (Per error GHC-65904, the interaction between the two extensions does not yet seem fully fleshed out.)\n\nIs there any fundamental obstruction to GHC exposing such a literal? I tried searching for prior discussion about this matter but came up empty-handed.\n\n* * *\n\n**Edit:** I should add that the best workaround of which I’m currently aware is to use the standard top-level-unlifted-value binding trick\n\n\n myNullAddr# :: (# #) -> MyAddr#\n myNullAddr# = \\ _ -> WrapAddr# nullAddr#\n\n\nIt might not be abominable, but it sure doesn’t spark any joy…",
"title": "Why no exposed `NullAddr#` literal?"
}