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