{
  "$type": "site.standard.document",
  "bskyPostRef": {
    "cid": "bafyreifcwrdom6mwsxkyyjyenmwur7nqn4qjg6miy6zkg3ghx54p3l74ne",
    "uri": "at://did:plc:pi6woz4d47bkuws673w2il2r/app.bsky.feed.post/3moaelrieh5n2"
  },
  "path": "/t/haskells-missing-mutable-reference-type/14248?page=3#post_45",
  "publishedAt": "2026-06-14T08:27:23.000Z",
  "site": "https://discourse.haskell.org",
  "tags": [
    "Fork-fragile reader-like operations in Haskell",
    "A reference implementation of IOScopedRef",
    "Effects for Less",
    "@danidiaz"
  ],
  "textContent": "prophet:\n\n> But then the question is: are there real functions that look like `libFun`? … takes a function from `IO _ -> IO _`\n\nYes, that’s what Fork-fragile reader-like operations in Haskell catalogues. You’ll see a couple of them are even in `base`. Some of them work directly on `IO`, some on `MonadIO m` or `MonadUnliftIO m`, but …\n\nprophet:\n\n> this function has to act on exactly `IO`. If you generalized it to work on any `m` that implements `MonadIO` (Or `MonadUnliftIO`) … you could instantiate `m` with `ReaderT Logger IO`\n\n(`MonadIO` will not be enough in the general case because it doesn’t allow lifting things like `catch`, `bracket`, `forkIO`, etc.. So, in the general case, we may need as much as `MonadUnliftIO`.)\n\nIs `MonadUnliftIO` good enough? Functionally yes, practically no. I address this question in A reference implementation of IOScopedRef. Writing monadic code with an unknown bind is bad for performance, as explained by Alexis King in _Effects for Less_.\n\nprophet:\n\n> You could special case the case where you’re using it with `bracket` (which calls its continuation exactly once in a predictable way)\n\nAh yes, that’s unfortunate. Maybe we could have a `Bracket` type that abstracts acquire and release. Alternatively, speculatively, a linearly typed continuation?\n\nprophet:\n\n> danidiaz:\n>\n>> it’s convenient as an alternative to `ReaderT`\n>\n> The problem is that it’s _not_ an alternative because you still need to pass the `IOScopedRef` into whatever wants to access it\n\nThere are many examples in the ecosystem of global, top-level `IORef`s created with `unsafePerformIO`. I don’t like that style, but if others do they could do the same with `IOScopedRef`. (I didn’t describe a `newIOScopedRef` primitive in the article, but there’s no reason one couldn’t exist. Anyway, it seems from his comment below, @danidiaz doesn’t even want to do that.)\n\ndanidiaz:\n\n> IIUC, wouldn’t that force you to make `libFun` polymorphic over the monad?\n\nYes, with the inevitable performance consequences.",
  "title": "Haskell's missing mutable reference type"
}