{
  "$type": "site.standard.document",
  "bskyPostRef": {
    "cid": "bafyreignl4oi4huy2zhotjyybtrzfog5wt2qg2s5vjot5ntqrlw2nuavyq",
    "uri": "at://did:plc:pi6woz4d47bkuws673w2il2r/app.bsky.feed.post/3mnubxl43is62"
  },
  "path": "/t/haskells-missing-mutable-reference-type/14248#post_7",
  "publishedAt": "2026-06-09T13:06:41.000Z",
  "site": "https://discourse.haskell.org",
  "textContent": "OK, I think I probably understand what you mean. You mean that if you’re passing the logger around everywhere you may as well replace all instances of\n\n\n    modifySeverity logger f $ do\n      ...\n\n\nwith\n\n\n    logger <- modifySeverity logger f\n    ...\n\n\nand so you’re asking for an example where you _can’t_ do that transformation. Sure. First, notice that you can only do that transformation if you can see the call to `modifySeverity`. So the answer is that you can’t do that transformation anywhere that `modifySeverity` is being used in a way that the caller can’t see. For example, suppose I have a function from another library with this fype\n\n\n    libFun ::\n      (String -> IO ()) ->\n      (forall r. Int -> IO r -> IO r) ->\n      IO T\n\n\nThen if I have a `logger :: Logger` implemented with an `IOScopedRef` I can call `libFun` like\n\n\n    libFun\n      (\\s -> logMsg logger 0 s)\n      (\\i body -> modifySeverity (const i) body)\n\n\nThere’s no way I can do that with lexical scoping. `libFun` doesn’t know that `modifySeverity` might be used within it! I’m guessing that’s what you meant by “having a computation that already somehow captures the `IOScopedRef`”?\n\n* * *\n\nprophet:\n\n> Everything that (indirectly) uses this `IOScopedRef` needs to go through the `logger` variable anyway so you might as well use it to carry the state in a lexically scoped way.\n\nYeah, I think didn’t explain well what I meant. There are two subtly different questions:\n\n  1. Can you get something with the same API as `Logger` but without using `IOScopedRef`? (i.e. `modifySeverity` takes an explicit body)\n\nI think the answer is “no” and I suspect you don’t disagree with me, but if not then please do say because that would be very interesting!\n\n  2. Can you get something with a _different_ API to `Logger` that does the same job in some cases? (i.e. `modifySeverity` doesn’t take a body, rather the modification is observable in the continuation)\n\nThe answer is “yes”, as you demonstrate above.\n\n\n\n\nThe difference is important because only something with the _same_ API (i.e. `modifySeverity` takes a body) can be used with `libFun`.\n\nYour original question was\n\n> Do you have an example where this is useful to have?\n\nMy claim is that `Logger` is an API that is unachievable without `IOScopedRef`. That is, my `loggerExample` cannot be written _as written_ without `IOScopedRef`. Your original point was: but it can be written in a different way without `IOScopedRef`. That’s a fair point. I can say “the API itself is useful” but you could always come back and ask _why_ it’s more useful than the lexical scoping way. In which case, the response would be that the lexical scoping way is not sufficient to integrate with `libFun`. (Then someone might say \"well `libFun` should be different, which may be so, but I’d like to know how.) I’ll see if I can think of a way of making this clear in the article.",
  "title": "Haskell's missing mutable reference type"
}