## State Monads

Finally i got little bit about Haskell monads. There are lot of articles on net but Mike’s World-O-Programming is really excellent . Thanks to Divyanshu for pointing me to the link. Any way i am not going to write another monad tutorial because i am not fit for this topic. I wrote couple of codes using state monads.

import Control.Monad import Control.Monad.State import System.Random --from wiki books about Haskell rollDice :: Int -> State StdGen Int rollDice n = get >>= ( \s -> ( return $ randomR ( 1 , n ) s ) >>= ( \ ( v , n ) -> put n >> return v ) ) gcD :: State ( Integer , Integer ) Integer gcD = get >>= ( \( a , b ) -> case b == 0 of True -> put ( a , a ) >> return a --change the state before returning the result just for fun _ -> put ( b , mod a b ) >> gcD ) fibo :: Int -> State ( Integer , Integer , Int ) Integer fibo n = get >>=( \( a , b , t ) -> case t == n of True -> return a _ -> put ( b , a + b , t + 1 ) >> fibo n ) fib :: State ( Integer , Integer ) () fib = get >>= ( \( a , b ) -> put ( b , a + b ) ) binaryGcd :: State ( Integer , Integer , Int ) Integer binaryGcd = get >>=( \( u , v , k ) -> case () of _ | u == 0 -> return ( v * 2 ^ k ) | v == 0 -> return ( u * 2 ^ k ) | and [ even u , even v ] -> put ( div u 2 , div v 2 , succ k ) >> binaryGcd | and [ even u , odd v ] -> put ( div u 2 , v , k ) >> binaryGcd | and [ odd u , even v ] -> put ( u , div v 2 , k ) >> binaryGcd | otherwise -> if u >= v then put ( div ( u - v ) 2 , v , k ) >> binaryGcd else put ( div ( v - u ) 2 , u , k ) >> binaryGcd ) findMax :: Int -> State Int () findMax n = get >>= ( \x -> case () of _ | x > n -> put ( x ) | otherwise -> put ( n ) ) sumList :: [ Integer ] -> State Integer Integer sumList [] = get >>=(\t -> return t ) sumList ( x : xs ) = get >>= ( \ t -> put ( t + x ) >> sumList xs ) sum' :: State ( Integer , Integer ) Integer sum' = get >>=( \( a , b ) -> return $ a + b ) --here we don't need to change the state main = do print $ evalState ( rollDice 1000 ) ( mkStdGen 1000) print $ evalState gcD ( 12345 , 3123123 ) print $ evalState ( fibo 10 ) ( 0 , 1 , 1 ) -- first two term 0 and 1 and count 0 print $ evalState binaryGcd ( 12345 , 3123123 , 0 ) print $ execState ( mapM findMax [ 1.. 10 ] ) 0 --remember our maximum value will be kept in state variable print $ fst . execState ( replicateM ( 10 - 1 ) fib ) $ ( 0 , 1 ) --to get nth decrase it one [ replicateM ( n - 1 ) fib ] print $ evalState ( sumList [ 1..10 ] ) 0 print $ evalState sum' ( 10 , 100 )

Advertisements