# My Weblog

## Blog about programming and math

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 System.Random

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 )
```

August 24, 2011 Posted by | Programming | , | 1 Comment