Change a light bulb

Shawn P. Garbett Shawn@Garbett.org
Fri, 1 Mar 2002 12:29:05 -0600


-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

I finally got a clue. I got the Haskell program working. Now to build upon 
it. Jay's comment really made the IO monad concept sink in for me.

Also reading through Manuael M T Chakravarty's Boolean editor was mind 
expanding as well. 

My biggest question is how to simplify, make more efficient, make more lazy 
what I have here. 

There's so much more to do now.....

- -- State model of a light bulb with IO

import Monad
import IO

main :: IO ()
main =  do 
          -- Turn off buffering so response is immediate
          hSetBuffering stdin NoBuffering 
          hSetBuffering stdout NoBuffering
          -- Process from the intialState
          process initialState
          return ()

- -- A generic state-machine processor
process    :: State -> IO ()
process st =  do

                -- retrieve current stimulus
                s <- getStimulus 
                putChar '\n'

                -- compute new state and response
                (r, st') <- do { return (s st) }

                -- do the specified response
                r

                -- if the state is lambda then exit
                if( st' /= Lambda)
                  then process st'
                  else return ()

- -- Now define state for our humble lightbulb
- -- State definition
data State = Dark | Light | Lambda
             deriving (Show, Eq, Enum)

- -- The inital state
initialState :: State
initialState =  Dark
          

- -- Response definitions
type Response = IO ()

activate :: Response
activate =  putStr "Haskell said, let there be light.\n"

deactivate :: Response
deactivate =  putStr "And darkness was upon the void.\n"


- -- Here is the state transforms (i.e. stimuli)
type Stimulus = State -> (Response, State)

on        :: Stimulus
on Dark   =  (activate,   Light)
on Light  =  (return (),  Light)

off       :: Stimulus
off Dark  =  (return (),  Dark)
off Light =  (deactivate, Dark)

exit      :: Stimulus
exit x    =  (return (),  Lambda)

- -- Create a stimulus source from stdin
charToStimulus     :: Char -> Stimulus
charToStimulus '1' =  on
charToStimulus '0' =  off
charToStimulus c   =  exit

getStimulus :: IO Stimulus
getStimulus =  liftM charToStimulus getChar


Shawn
- -- 
You're in a maze of twisty little statements, all alike.
Public Key available from http://www.garbett.org/public-key
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.0.6 (GNU/Linux)
Comment: For info see http://www.gnupg.org

iD8DBQE8f8hxDtpPjAQxZ6ARAtWFAJ9fQ7rURyKebnSlBvrEklBSqnnb1QCdHHtM
I4nSaTg0Sl2vIz+Yx1Z7ab8=
=FKTr
-----END PGP SIGNATURE-----