In Haskell, IORef helps us get imperative code that runs in the IO monad. The ST variant allows us to use mutable computations purely.
-- Imperative version of the factorial.
import Data.IORef
import Control.Monad.Loops
factorial :: Int -> IO Int
factorial n = do
accumulator <- newIORef 1
number <- newIORef n
whileM_ (readIORef number >>= (\i -> return $ i > 0)) $ do
i' <- readIORef number
a' <- readIORef accumulator
writeIORef accumulator (a' * i')
writeIORef number (i' - 1)
a' <- readIORef accumulator
return a'
There are ways of making this less ugly and more C-like (see CStyle).
Tags: Haskell.