{-- A dummy monad transformer GUI for Gui programming whose functionality has been lifted to class Gui. This module is almost identical (except identifiers) to Db.hs --} module Gui ( Gui, gui, GUI, guiExampleOp ) where import Io import STM import MonadT -- (in this example it is assumed that Gui implies Io for some reason): class Io m => Gui m where gui :: GUIImpl m -- monad transformer GUI: newtype GUI m a = GUI (STM GUIStat m a) fromGUI (GUI a) = a toGUI = GUI instance Monad m => Functor (GUI m) where fmap f = toGUI . fmap f . fromGUI instance Monad m => Monad (GUI m) where m >>= f = toGUI ((fromGUI m) >>= (fromGUI . f)) return = toGUI . return instance MonadT GUI where lift = toGUI . lift start = run 0 . fromGUI instance Io m => Io (GUI m) where io = lift . io instance Io m => Gui (GUI m) where gui = GUIImpl (toGUI . modify) -- state type GUIStat = Int -- ADT that encapsulates monad operations: data GUIImpl m = GUIImpl ((GUIStat -> GUIStat) -> m GUIStat) instance Liftable GUIImpl where mapLift (GUIImpl m) = GUIImpl (lift . m) -- some example class op: set state & read it & print: guiExampleOp :: Gui m => Int -> m () guiExampleOp i = do modify (\_ -> i) result <- modify id putStrC (show result) where (GUIImpl modify) = gui