[GUI] Re: GUI Library Task Force

Andy Gill andy@galconn.com
Tue, 25 Sep 2001 10:38:21 -0700


"Manuel M. T. Chakravarty" wrote:

> * I am not a big fan of introducing an extra monad (`GUI' in
>   this case).  It can easily become a pain in programs that
>   do a lot of "normal" IO as you have to lift all IO
>   functions to GUI.

So you want various IO operations, that act not only in the IO monad,
but in other monads also? Perhaps something like

  putStrLn :: (MonadIO io) => String -> io ()

Then writing you IO operations inside your GUI becomes trivial.

Lets push this a bit with an implementation.

-- a way of tunneling into the IO Monad
class (Monad m) => MonadIO m where
   runIO :: IO v -> m v

-- and the "default" IO monad.
instance MonadIO IO where
   runIO m = m

-- a sample GUI
newtype GUI a = GUI { unGUI :: IO a }

-- wibble
instance Monad GUI where
   return a = GUI (return a)
   (GUI m) >>= k = GUI (m >>= \ r -> unGUI (k r))

-- how the GUI tunnels
instance MonadIO GUI where
   runIO m = GUI m

-- and an implementation of putStrLn
putStrLn :: (MonadIO io) => String -> io ()
putStrLn str = runIO (Prelude.putStrLn str)

-- You need to import the Prelude hiding putStrLn,
-- the import putStrLn qualified, but it should be
-- possible to develop a module that contains
-- your favorite IO monadic things, behind which
-- this magic is hidden.

(I'm not arguing for/against the Clean GUI, but one of your points of
reasoning).

--
Andy Gill
Galois Connections