
Hi Tilmann,
wxApp :: (MonadReader Handle m, MonadIO m) => m () wxApp = do ping -- this works, but I don't need it here.. liftIO $ do f <- frame [ ] timer f [ interval := 1000 -- , on command := hputStrLn h "ping" -- this is what I try to avoid -- , on command := ping -- of course, this doesn't work, but it would be so nice.. , enabled := True] return ()
I assume that WX expects an 'IO' action for the 'command', but 'ping' is an action of the 'ReaderT' monad. WX won't be able to execute this action, because it doesn't know anything about the 'ReaderT' monad, so there's no 'Handle' that it could give to the 'ping' function. I think the most straight forward solution is to have a function 'ping': ping :: Handle -> IO () ping h = hputStrLn h "ping" And then a 'wxApp' like: wxApp :: (MonadReader Handle m, MonadIO m) => m () wxApp = do handle <- ask liftIO $ do f <- frame [ ] timer f [ interval := 1000, on command := ping handle, enabled := True] return () So instead of having 'ping' in the 'ReaderT' monad you just give it explicitly the data of the monad. You could have a helper function that does this transformation: handlize :: (MonadReader Handle m, MonadIO m) => (Handle -> IO()) -> m (IO ()) handlize func = do handle <- ask return $ func handle wxApp :: (MonadReader Handle m, MonadIO m) => m () wxApp = do cmd <- handlize ping liftIO $ do f <- frame [ ] timer f [ interval := 1000, on command := cmd, enabled := True] return () Greetings, Daniel