-- State monad type Register = Bool data State a = State ( Register -> ( Register , a ) ) instance Monad State where return a = State ( \r -> ( r , a )) (State st) >>= f = State ( \r -> let ( newst, x ) = st r (State trans) = f x in trans newst ) -- Function to check the state isOn :: State Bool isOn = State ( \r -> ( r , r ) ) -- Function to toggle the state. toggle :: State () toggle = State ( \r -> ( not r , () ) ) --Simple function to output upper or --lower case characters based on the state. tuUpper :: Register -> Char -> Char tuUpper True c = toUpper c tuUpper _ c = c main :: IO () main = interact process --Process the input mProcess :: String -> State String mProcess (s:sx) = do b <- isOn if ( s == 't' ) then toggle else return () appOut (tuUpper b s) (mProcess sx) --Compose the output into a string appOut :: Char -> State String -> State String appOut c m = do str <- m return ([c] ++ str) --Extracts the answer from --a series of monadic calculations extract :: State a -> a extract (State k) = snd ( k False ) process = extract.mProcess