I am trying to learn how to use the ST Monad. I wonder if it is possible to print values as actions are taken. For example with a Fibonacci function in the ST Monad:
fibST :: Integer -> Integer
fibST n
| n < 2 = n
| otherwise =
runST $ do
a <- newSTRef 0
b <- newSTRef 1
go n a b
where
go 0 a _ = readSTRef a
go n a b = do
a' <- readSTRef a
b' <- readSTRef b
writeSTRef a b'
writeSTRef b (a' + b')
-- print "SOME INFORMATION HERE" <---
go (n - 1) a b
What would I have to do in this case?
@Vikstapolis suggested to use IORef instead
fibIO :: Integer -> IO Integer
fibIO n
| n < 2 = pure n
| otherwise =
do
a <- newIORef 0
b <- newIORef 1
go n a b
where
go 0 a _ = readIORef a
go n a b = do
a' <- readIORef a
b' <- readIORef b
writeIORef a b'
writeIORef b (a' + b')
print a' -- intermediate values
go (n - 1) a b
TLDR: No, you cannot use print or other IO-related functions in the ST monad. Use IORefs in the IO monad for both mutability and the ability to print values.
Full answer:
In Haskell, every value is immutable. This helps preserve its purity. Purity also does not allow side effects such as printing or user input.
A program which cannot take input or print output, however, is useless. So, Haskell has explicit impure functions within the IO monad. By means of IORefs, you can also have mutability within the IO monad.
But sometimes, you need to use mutability to increase the efficiency of a function, and can guarantee that the function is pure or referentially transparent (i. e. The same input will always give the same output). This is the purpose of the ST monad.
The ST monad doesn’t allow arbitrary side effects such as printing, since that would destroy its purity. It only allows interior mutation within it, and once you escape the monad using runST, it appears as a pure computation to the rest of the program.
So, if you really need to print values and have mutation, use IORefs in the IO monad. For pure functions with interior mutation, use ST.
Note: it is possible to add IO to pure functions with unsafePerformIO, and to ST with unsafeIOToST. As the name indicates, they are unsafe and should be avoided unless absolutely necessary (which they usually aren’t).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With