
At Sun, 23 Aug 2009 16:23:54 +0200, Levi Greenspan wrote: What you probably want is: test2' :: IO () test2' = runM "foo" $ do loop callback liftIO $ print "here" Taking a look at your version:
test2 :: IO () test2 = runM "foo" $ liftIO $ do return $ loop callback print "here"
Since 'print' has the type IO (), this whole do statement has the type IO (): do return $ loop callback print "here" In isolation, we see the following expression has the type: *Main> :t return $ loop callback return $ loop callback :: (Monad m) => m (M ()) so, in context it has the type: return $ loop callback :: (Monad m) => IO (M ()) It is an IO operation which returns a value of type, M (). But, nothing is done with that value, it is just thrown away. We could hack it to work like this: test2'' :: IO () test2'' = runM "foo" $ liftIO $ do m <- return $ loop callback runM "m" m print "here" but test2' seems better. If you want to add a forkIO, the forkIO must go before the runM: testFork :: IO ThreadId testFork = forkIO $ runM "foo" $ do loop callback liftIO $ print "here" Let's say we try to put it after the runM: testFork :: IO ThreadId testFork = runM "foo" $ forkIO $ do loop callback liftIO $ print "here" This will fail with the error: Couldn't match expected type `M ()' against inferred type `IO ()' Because runM expects something of type M (), but forkIO has the type IO ThreadId. So, we can use liftIO to convert the forkIO into a value of type M: testFork :: IO ThreadId testFork = runM "foo" $ liftIO (forkIO $ do loop callback liftIO $ print "here") Now we get the error: Couldn't match expected type `M ()' against inferred type `IO ()' In a stmt of a 'do' expression: loop callback because forkIO expects values of type IO (), but the do block has the type M (). So, we can use runM to convert the M () to an IO () testFork :: IO ThreadId testFork = runM "foo" $ liftIO (forkIO $ do runM "loop" $ loop callback print "here") But, we see that we are now back to the position of having the forkIO before the (second) runM. We can simplfy that expression to just: testFork :: IO ThreadId testFork = forkIO $ do runM "loop" $ loop callback print "here" hope this helps. - jeremy