Changing a light bulb.

Shawn P. Garbett
Thu, 28 Feb 2002 15:55:53 -0600

Hash: SHA1

Now after my earlier soap box tirade I'm trying to put my code where my mouth 
is. >>blush<< It's harder than I thought. 

I've broken it down into a State Model of a light bulb. The goal, to find out 
just how much Haskell code does it take to change the state of a light bulb?

Here's a very crippled version. Is there an easy way to introduce state
without changing the type of main???

I've written a much more complex example, but I got into things like

main :: STT(IO)

using a monad transformer.

So really, the big question is, must I use a monad transformer?
- ------------------------------------------------------------------------------------------------
- -- State model of a light bulb

import Monad
import IO

main :: IO ()
main = do 
         hSetBuffering stdin NoBuffering

process :: IO ()
process =  do
             i <- assign initialState
             putChar '\n'
             if (s /= Exit)
               then process
               else return ()

data State = Dark | Light

initialState :: State
initialState =  Dark

data Stimulus = On | Off | Exit
                deriving (Show, Eq, Enum)

charToStimulus :: Char -> Stimulus
charToStimulus '1' = On
charToStimulus '0' = Off
charToStimulus c   = Exit

getStimulus :: IO Stimulus
getStimulus =  liftM charToStimulus getChar

- -- State transformer
newtype St a = MkSt (State -> (a, State))

- -- State transformer applied to state
apply             :: St a -> State -> (a, State)
apply (MkSt f) s  = f s

- -- State monad

instance Monad St where
  return x  = MkSt f where f s = (x,s)
  p >>= q   = MkSt f where f s = apply (q x) s'
                                 where (x, s') = apply p s

- -- Useful State operations
fetch :: St State
fetch =  MkSt f where f s = (s,s)

assign    :: State -> St ()
assign s' =  MkSt f where f s = ((),s')

done :: St ()
done = return ()
- -----------------------------------------------------------------------------------------------------------------------

- -- 
You're in a maze of twisty little statements, all alike.
Public Key available from
Version: GnuPG v1.0.6 (GNU/Linux)
Comment: For info see