{
  "$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?"
}