[Haskell-cafe] Multiple State Monads
Luke Palmer
lrpalmer at gmail.com
Thu Jan 15 20:28:57 EST 2009
On Thu, Jan 15, 2009 at 3:34 PM, Phil <pbeadling at mail2web.com> wrote:
> On 14/01/2009 01:08, "Luke Palmer" <lrpalmer at gmail.com> wrote:
>
> On Tue, Jan 13, 2009 at 5:45 PM, Phil <pbeadling at mail2web.com> wrote:
>
> mcSimulate :: Double -> Double -> Word64 -> [Dou
> ble]
> mcSimulate startStock endTime seedForSeed = fst expiryStock : mcSimulate
> startStock endTime newSeedForSeed
>
> It is abundantly clear that the startStock and endTime are just being
> passed around from call to call unchanged – that is their value is constant
> throughout the the simulation. For the purposes here when I'm only passing
> 2 'constants' around it doesn't strike me as too odd, but my list of
> 'constants' is likely to grow as I bolt more functionality onto this. For
> readability, I understand that I can create new types to encapsulate complex
> data types into a single type , but I can't help thinking that passing say 9
> or 10 'constants' around and around like this 'feels wrong'. If I sit back
> and think about it, it doesn't strike me as implausible that the compiler
> will recognize what I'm doing and optimize this out for me, and what I'm
> doing is thinking about the whole think like a C++ programmer (which I
> traditionally am) would.
>
>
> You can factor out constants in a couple ways. If you are just passing
> constants between a recursive call to the same function, you can factor out
> the recursive bit into a separate function:
>
> something param1 param2 = go
> where
> go = ... param1 ... param2 ... etc ... go ...
> etc = ...
>
> Where go takes only the parameters that change, and the rest is handled by
> its enclosing scope. You might buy a little performance this way too,
> depending on the compiler's cleverness (I'm not sure how it optimizes these
> things).
>
>
> [PHIL]
> Firstly – thanks for your advice.
>
> When I say constants, I should be clear – these are parameters passed in by
> the user, but they remain constant throughout the recursive call. I think
> the example above is only relevant if they are constants at compile time?
> If not I'm not sure I follow the example. If we have something like
>
> 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
>
> Here startStock and endTime are not altered from iteration to iteration,
> but they are not known at compile time. I see that I can reduce this to
> something like
>
> test seedForSeed = fst expiryStock : test newSeedForSeed
> where
> expiryStock = iterate evolveUnderlying (_startStock, ranq1Init
> seedForSeed) !! truncate (_endTime/timeStep)
> newSeedForSeed = seedForSeed + 246524
>
> But don't understand how I 'feed' the _startStock and _endTime in?
>
> Could you explain this in detail, or confirm my suspicions that it only
> works for compile-time constants?
>
>
Compile-time constants could be handled by simple top-level bindings. This
technique is specifically for the case you are after:
mcSimulate :: Double -> Double -> Word64 -> [Double]
mcSimulate startStock endTime seedForSeed = go seedForSeed
where
go = fst expiryStock : go newSeedForSeed
where
expiryStock = iterate evolveUnderlying (startStock, ranq1Init
seedForSeed)
!! truncate (endTime/timeStep)
newSeedForSeed = seedForSeed + 246524
See what's going on there?
I don't know about that nested where. In Real Life I would probably use a
let instead for expiryStock and newSeedForSeed.
Luke
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20090115/cc27306f/attachment.htm
More information about the Haskell-Cafe
mailing list