I have a small program that defines an account, a withdraw function and attempts to withdraw from it. However, it doesn't compile due and throws the following error:
Couldn't match expected type ‘(STM a0 -> IO a0)
-> STM () -> IO ()’
with actual type ‘IO ()’
It seems like the compiler doesn't recognise the conversion from STM to IO. Any pointers would be great.
import System.IO
import Control.Concurrent.STM
type Account = TVar Int
withdraw :: Account -> Int -> STM ()
withdraw acc amount = do
bal <- readTVar acc
writeTVar acc (bal - amount)
good :: Account -> IO ()
good acc = do
hPutStr stdout "Withdrawing..."
{-hi-}atomically{-/hi-} (withdraw acc 10)
main = do
acc <- atomically (newTVar 200)
good acc
hPutStr stdout "\nDone!\n"
The {-hi-}
and {-/hi-}
comment result in "indenting" the automically
, so as a result, you wrote hPutStr stdout "Withdrawing..." atomically (withdraw acc 10)
. For example if you write:
good :: Account -> IO ()
good acc = do
hPutStr stdout "Withdrawing..."
{-hi-} atomically (withdraw acc 10)
it works fine, since the "noise" (the {-hi-}
comment) does not result in inlining the atomically
function.
The comment indeed has no effect semantically, but you can consider it replaced by whitespace.