[Haskell-cafe] Multiple State Monads

Phil pbeadling at mail2web.com
Mon Jan 12 15:20:19 EST 2009


I¹ve been reading the Monads aren¹t evil posts with interest ­ I¹m a 2nd
week Haskell newbie and I¹m doing my best to use them where (I hope) it is
appropriate.  Typically I¹m writing my code out without using Monads
(normally using list recursion), and then when I get them working, I delve
into the Monad world.... This has been going well so far with a bit of help
from you guys, but I¹ve hit a snag.

In the code below I¹m using a state Monad (getEvolution), but unlike simpler
cases I¹m passing around two items of state, and one of these states is also
ultimately a result ­ although I don¹t care about the result until I reach
an end state.  My implementation is a bit ugly to say the least and clearly
I¹m forcing round pegs into square holes here ­ reading a bit online I get
the impression that I can solve the two-state issue using Monad
Transformers, by  wrapping a StateT around a regular State object (or even
two StateT Monads around an Identity Monad??).  I think I understand the
theory here, but any attempt to implement it leads to a horrible mess that
typically doesn¹t compile.  The other problem of having a state that is also
a result, I¹m sure what to do about this.

Was wondering if anyone could give me a push in the right direction ­ how
can I rework my state monad so that it looks less wildly.

Many thanks,


mcSimulate :: Double -> Double -> Word64 -> [Double]
mcSimulate startStock endTime seedForSeed = expiryStock : mcSimulate
startStock endTime newSeedForSeed
    expiryStock =  evalState ( do replicateM_ (truncate(endTime/timeStep)-1)
getEvolution; getEvolution )
                   $ (startStock,ranq1Init seedForSeed)
    newSeedForSeed = seedForSeed + 246524

discount :: Double -> Double -> Double -> Double
discount stock r t = stock * exp (-r)*t

payOff :: Double -> Double -> Double
payOff strike stock | (stock - strike) > 0 = stock - strike
                    | otherwise = 0

-- Monad Implementation

-- Yuk! 
evolveUnderlying :: (Double, Word64) -> ( Double, (Double, Word64) )
evolveUnderlying (stock, state) = ( newStock, ( newStock, newState ) )
    newState = ranq1Increment state
    newStock = stock * exp ( ( ir - (0.5*(vol*vol)) )*timeStep + (
vol*sqrt(timeStep)*normalFromRngState(state) ) )

getEvolution :: State (Double, Word64) Double
getEvolution = State evolveUnderlying

-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090112/e7c79810/attachment.htm

More information about the Haskell-Cafe mailing list