On Tue, Jan 13, 2009 at 5:29 PM, Phil <pbeadl...@mail2web.com> wrote: > Many thanks for the replies. > > Using 'modify' cleans the syntax up nicely. > > With regard to using 'iterate' as shown by David here: > >>> mcSimulate :: Double -> Double -> Word64 -> [Double] >>> mcSimulate startStock endTime seedForSeed = fst expiryStock : mcSimulate >>> startStock endTime newSeedForSeed >>> where >>> expiryStock = iterate evolveUnderlying (startStock, ranq1Init >>> seedForSeed) >>> !! truncate (endTime/timeStep) >>> newSeedForSeed = seedForSeed + 246524 > > My only concern with using this method is - Will 'iterate' not create a full > list of type [Double] and then take the final position once the list has > been fully realized?
iterate creates the elements of the list as they are requested, and !! will discard everything until it hits the answer it wants. That being said, it's not the best way to repeatedly apply a function, as Luke pointed out. A better way would probably be something like this, applyNTimes :: Int -> (a -> a) -> a -> a applyNTimes n f a | n <= 0 = a | otherwise = applyNTimes (n-1) $! f a That ($!) is there to make sure "f a" gets evaluated before calling applyNTimes again. > The key reason for using the Monad was to tell Haskell to discard all but > the current state. If I'm wrong about please let me know, as I don't want > to be guilty of overcomplicating my algorithm, and more importantly it means > I'm not yet totally grasping the power of Haskell! I'm not entirely sure what you mean by "discard all but the current state", but Haskell implementations are pretty good about discarding values that are no longer needed. That being said, here's one way I might implement your algorithm. It's a sketch, and I haven't tested it, but the general idea should be clear. mcSimulate stock endTime seed = map (evolve n stock) $ iterate (+246524) seed where n = truncate (endTime / timeStep) evolve :: Int -> Double -> Word64 -> Double evolve n stock seed | n <= 0 = stock | otherwise = evolve (n-1) (evolveStock stock seed) (ranq1Increment seed) evolveStock :: Double -> Word64 -> Double evolveStock stock seed = stock * exp (a + b * normalFromRngState seed) where a = (ir - 0.5 * vol * vol) * timeStep b = vol * sqrt timeStep -- Dave Menendez <d...@zednenem.com> <http://www.eyrie.org/~zednenem/> _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe