{
"$type": "site.standard.document",
"bskyPostRef": {
"cid": "bafyreiacquptihbjjxg2viqvusun3dm56tovr5qxv3cmq7sj2c3mujf7nu",
"uri": "at://did:plc:pi6woz4d47bkuws673w2il2r/app.bsky.feed.post/3mnuceq5qxk62"
},
"path": "/t/haskells-missing-mutable-reference-type/14248#post_6",
"publishedAt": "2026-06-09T12:39:49.000Z",
"site": "https://discourse.haskell.org",
"textContent": "Oops, i did misread the example slightly sorry ^^ You’re using the `IOScopedRef` to implement `modifySeverity` not to modify the `Logger` value directly.\n\nMy point still stands though. 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\n> OK, then tell me how I could obtain the same behaviour using a lexically-scoped variable but without `IOScopedRef`.\n\n\n data Logger = Logger {\n logImpl :: Severity -> String -> IO (),\n baseSeverity :: Severity\n }\n\n logMsg :: Logger -> Severity -> String -> IO ()\n logMsg logger severity msg = logger.logImpl (logger.baseSeverity + severity) msg\n\n newLogger :: Severity -> Logger\n newLogger baseSeverity = Logger { baseSeverity, logImpl = \\severity message -> putStrLn ... }\n\n modifySeverity :: Logger -> (Severity -> Severity) -> Logger\n modifySeverity logger f = logger { baseSeverity = f logger.baseSeverity }\n\n loggerExample :: IO ()\n loggerExample = do\n let logger = newLogger 0\n logMsg logger 1 \"Getting user\"\n user <- getUser\n logMsg logger 1 (\"Is VIP: \" <> show (isVip user))\n let modification = if isVip user then (+ 10) else id\n d <- do\n logger <- pure (modifySeverity logger modification)\n logMsg logger 0 \"Getting data\"\n getData user\n writeData d\n logMsg logger 0 \"Done\"\n",
"title": "Haskell's missing mutable reference type"
}