Here is my attempt to write the infamous factorial using Data.IORef.
import Data.IORef
xgo accRef nRef = go where
go = do
acc <- readIORef accRef
n <- readIORef nRef
writeIORef accRef (acc * n)
writeIORef nRef (n - 1)
if (n > 2) then go else readIORef accRef
facM n = do
accRef <- newIORef 1
nRef <- newIORef n
xgo accRef nRef
This code is supposed to be an example for dummies on how to use IORefs, so certainly I want to keep it simple -- e.g. no tuples and no lens. But the whole xgo thing seem artificial. Can we have xgo defined within facM? What is the most idiomatic way to write IORef code like this (of course I don't mean avoiding IORef, we all know the fac n = prod [1..n] solution here).
Upd: I got it to:
facM n = do
accRef <- newIORef 1
nRef <- newIORef n
let xgo = go where {
go = do
acc <- readIORef accRef
n <- readIORef nRef
writeIORef accRef (acc * n)
writeIORef nRef (n - 1)
if (n > 2) then go else readIORef accRef
}
xgo
So there are no second accRef/nRef anymore, but there is still this xgo/go separation. Somehow I can't get xgo = do { ... } working without an intermediate go