Help using a state monad
Tom Bevan
tom@regex.com.au
14 Jan 2002 16:58:15 +1100
--=-cSZMBXDBPCagvkaSVqyo
Content-Type: text/plain
Content-Transfer-Encoding: 7bit
Hi all,
I'm trying to get a feel for how monads might be used in a Haskell
program and develop an approach that would be useful for larger
projects.
I have tried to model in miniture a programme which takes input from
'standard in' and processes it against an internal state and then
returns the processed result to 'standard out'.
My problem is that, becuase of the way I have constructed the programme
'standard out' lags behind by one character.
I'm hoping that someone might have a better design they could share with
me.
Tom.
--=-cSZMBXDBPCagvkaSVqyo
Content-Disposition: attachment; filename=scratch.hs
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=ISO-8859-1
-- State monad
type Register =3D Bool
data State a =3D State ( Register -> ( Register , a ) )
instance Monad State where
return a =3D State ( \r -> ( r , a ))
(State st) >>=3D f =3D State ( \r -> let=20
( newst, x ) =3D st r
(State trans) =3D f x
in=20
trans newst )=20
-- Function to check the state
isOn :: State Bool=20
isOn =3D State ( \r -> ( r , r ) )
-- Function to toggle the state.
toggle :: State ()
toggle =3D State ( \r -> ( not r , () ) )
--Simple function to output upper or
--lower case characters based on the state.
tuUpper :: Register -> Char -> Char
tuUpper True c =3D toUpper c
tuUpper _ c =3D c
main :: IO ()
main =3D interact process
--Process the input
mProcess :: String -> State String
mProcess (s:sx) =3D do b <- isOn
if ( s =3D=3D '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 =3D do str <- m
return ([c] ++ str)
--Extracts the answer from
--a series of monadic calculations
extract :: State a -> a
extract (State k) =3D snd ( k False )
process =3D extract.mProcess=20
--=-cSZMBXDBPCagvkaSVqyo--