On Thu, Jan 15, 2009 at 3:34 PM, Phil <pbeadl...@mail2web.com> wrote:
> On 14/01/2009 01:08, "Luke Palmer" <lrpal...@gmail.com> wrote: > > On Tue, Jan 13, 2009 at 5:45 PM, Phil <pbeadl...@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
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe