[Haskell-cafe] Monad woes

Levi Greenspan greenspan.levi at googlemail.com
Sun Aug 23 10:23:54 EDT 2009


Hi all,

I try to create a simple monad using a stack of Reader and IO but when
using it, I encounter some problems. The Monad is defined as M a:

{-# LANGUAGE GeneralizedNewtypeDeriving #-}
module Main where

import Control.Monad.Reader
import Control.Concurrent

newtype M a = M {
        unM :: ReaderT String IO a
    } deriving (Monad, MonadIO, MonadReader String)

runM :: String -> M a -> IO a
runM s m = runReaderT (unM m) s

loop :: (String -> M ()) -> M ()
loop f = forever $ f "hello"


I then define a callback function to be invoked by 'loop':


callback :: String -> M ()
callback s = liftIO $ print s >> threadDelay 1000000


So far so good. Then I test it like this:


test1 :: IO ()
test1 = runM "foo" $ do
    loop callback
    liftIO $ print "here" -- OK. Never reached


Still works fine. 'loop' never returns. In a real life application
'loop' is an event loop and I'd like to fork it into a new thread like
this:


test3 :: IO ()
test3 = runM "foo" $ liftIO $ do
    forkIO $ do
        return $ loop callback
        return ()
    print "here"
    threadDelay 2000000


This not only looks ugly, it also doesn't work. For 'loop callback' to
pass the type checker, it had to be returned into the IO monad. But I
guess due to laziness, 'loop' will never be called. This can be
confirmed without forkIO:


test2 :: IO ()
test2 = runM "foo" $ liftIO $ do
    return $ loop callback
    print "here"


Again, 'loop callback' will not be invoked.

Now, given that I must find a way to combine IO and my M monad I don't
know what to try next. Prima facie it seems I must somehow force 'loop
callback' to be evaluated, but how? Not to mention all the liftIO
clutter. I would greatly appreciate some help here.

Thank you very much!

Cheers,
Levi
-------------- next part --------------
A non-text attachment was scrubbed...
Name: Test.hs
Type: text/x-haskell
Size: 872 bytes
Desc: not available
Url : http://www.haskell.org/pipermail/haskell-cafe/attachments/20090823/6842ab4c/Test.bin


More information about the Haskell-Cafe mailing list