Software Transaction Memory in Haskell: Couldn't match expected type STM a0 with actual type IO ()

Viewed 166

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"
1 Answers

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.

Related