On Tue, Jan 13, 2009 at 5:45 PM, Phil <span dir="ltr">&lt;<a href="mailto:pbeadling@mail2web.com">pbeadling@mail2web.com</a>&gt;</span> wrote:



<br><div class="gmail_quote"><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;"><div><font size="4"><font face="Calibri, Verdana, Helvetica, Arial"><span style="font-size: 11pt;"><div class="Ih2E3d">
mcSimulate :: Double -&gt; Double -&gt; Word64 -&gt; [Dou</div><span style="font-size: 14px;">ble]<br>
<span style="font-size: 11pt;"><div class="Ih2E3d">mcSimulate startStock endTime seedForSeed = fst expiryStock : mcSimulate startStock endTime newSeedForSeed<br>
<br></div>
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. &nbsp;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. &nbsp;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'. &nbsp;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. &nbsp;</span></span></span></font></font></div>
</blockquote><div><br>You can factor out constants in a couple ways.&nbsp; 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:<br><br>
<font face="courier new,monospace">something param1 param2 = go<br>&nbsp;&nbsp;&nbsp; where<br>&nbsp;&nbsp;&nbsp; go = ... param1 ... param2 ... etc ... go ... <br>&nbsp;&nbsp;&nbsp; etc = ...<br></font><br>Where go takes only the parameters that change, and the rest is handled by its enclosing scope.&nbsp; You might buy a little performance this way too, depending on the compiler&#39;s cleverness (I&#39;m not sure how it optimizes these things).<br>
<br>If you are passing around many constants between functions, first package them all up in a record data type:<br><br><font face="courier new,monospace">data Params = Params {<br>&nbsp;&nbsp;&nbsp; parmFoo :: Int,<br>&nbsp;&nbsp;&nbsp; parmBar :: Double,<br>
&nbsp;&nbsp;&nbsp; ... <br>&nbsp; }<br><br><font face="times new roman,serif">At this point it is pretty easy just to pass a Parms object around.&nbsp; If you really hate the explicit style, though, you can throw your computation into a Reader Parms&nbsp; (Reader is the monad precisely for this: adding a constant parameter to every function), and then use eg. <span style="font-family: courier new,monospace;">asks parmFoo</span> to get parameters out.<br>
<br>And if none of those strike your fancy, you can look into GHC&#39;s &quot;implicit arguments&quot; extension.&nbsp; But that seems to be in the process of a phase out by the community (nothing explicit, it&#39;s just that nobody is using them anymore).<br>
<br>Luke<br></font></font>&nbsp;</div><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;"><div><font size="4"><font face="Calibri, Verdana, Helvetica, Arial"><span style="font-size: 11pt;"><span style="font-size: 14px;"><span style="font-size: 11pt;"><br>

<br>
However before I allayed my own concerns I wanted to check that in the Haskell world passing around lots of parameters isn't a bad thing  that is, I'm not missing a trick here to make my code more readable or more importantly more performant.<br>

<br>
Thanks again,<br><font color="#888888">
<br>
Phil.</font><div><div></div><div class="Wj3C7c"><br>
<br>
On 13/01/2009 23:24, &quot;Luke Palmer&quot; &lt;<a href="mailto:lrpalmer@gmail.com" target="_blank">lrpalmer@gmail.com</a>&gt; wrote:<br>
<br>
</div></div></span></span></span></font></font><div><div></div><div class="Wj3C7c"><blockquote><font size="4"><font face="Calibri, Verdana, Helvetica, Arial"><span style="font-size: 11pt;"><span style="font-size: 14px;"><span style="font-size: 11pt;">On Tue, Jan 13, 2009 at 3:29 PM, Phil &lt;<a href="mailto:pbeadling@mail2web.com" target="_blank">pbeadling@mail2web.com</a>&gt; wrote:<br>

</span></span></span></font></font><blockquote><font size="4"><font face="Calibri, Verdana, Helvetica, Arial"><span style="font-size: 11pt;"><span style="font-size: 14px;"><span style="font-size: 11pt;">My only concern with using this method is - Will &#39;iterate&#39; not create a full<br>

list of type [Double] and then take the final position once the list has<br>
been fully realized? &nbsp;For my application this would be undesirable as the<br>
list may be millions of items long, and you only ever care about the last<br>
iteration (It&#39;s a crude Monte Carlo simulator to give it some context). &nbsp;If<br>
Haskell is smart enough to look ahead and see as we only need the last<br>
element as it is creating the list, therefore garbage collecting earlier<br>
items then this would work fine - by I&#39;m guessing that is a step to far for<br>
the compiler?<br>
</span></span></span></font></font></blockquote><font size="4"><font face="Calibri, Verdana, Helvetica, Arial"><span style="font-size: 11pt;"><span style="font-size: 14px;"><span style="font-size: 11pt;"><br>
No, doing this type of thing is very typical Haskell, and the garbage collector <i>will</i> incrementally throw away early elements of the list. <br>
<br>
</span></span></span></font></font><blockquote><font size="4"><font face="Calibri, Verdana, Helvetica, Arial"><span style="font-size: 11pt;"><span style="font-size: 14px;"><span style="font-size: 11pt;"><br>
I had originally implemented this similar to the above (although I didn&#39;t<br>
know about the &#39;iterate&#39; keyword<br>
</span></span></span></font></font></blockquote><font size="4"><font face="Calibri, Verdana, Helvetica, Arial"><span style="font-size: 11pt;"><span style="font-size: 14px;"><span style="font-size: 11pt;"><br>
FWIW, iterate is just a function, not a keyword. &nbsp;Could just be terminology mismatch.<br>
&nbsp;<br>
So, while the garbage collector will do the right thing, for a list millions of elements long, I suspect you will get stack overflows and/or bad memory performance because the computation is too lazy. &nbsp;One solution is to use a stricter version of !!, which evaluates elements of the list as it whizzes by them. &nbsp;Because the function you&#39;re iterating is strict to begin with, you do not lose performance by doing this:<br>

<br>
</span></span></span></font><span style="font-size: 11pt;"><span style="font-size: 14px;"><span style="font-size: 11pt;"><font face="Courier New">strictIdx :: Int -&gt; [a] -&gt; a<br>
strictIdx _ [] &nbsp;&nbsp;&nbsp;&nbsp;= error &quot;empty list&quot;<br>
strictIdx 0 (x:xs) = x<br>
strictIdx n (x:xs) = x `seq` strictIdx (n-1) xs<br>
</font><font face="Calibri, Verdana, Helvetica, Arial"><br>
(Note that I flipped the arguments, to an order that is nicer for currying)<br>
<br>
The reason is that iterate f x0 constructs a list like this:<br>
<br>
[ x0, f x0, f (f x0), f (f (f x0)), ... ]<br>
<br>
But shares the intermediate elements, so if we were to evaluate the first f x0 to, say, 42, then the thunks are overwritten and become:<br>
<br>
[ x0, 42, f 42, f (f 42), ... ]<br>
<br>
So iterate f x0 !! 1000000 is f (f (f (f ( ... a million times ... f x0)))), which will be a stack overflow because of each of the calls. &nbsp;What strictIdx does is to evaluate each element as it traverses it, so that each call is only one function deep, then we move on to the next one.<br>

<br>
This is the laziness abstraction leaking. &nbsp;Intuition about it develops with time and experience. &nbsp;It would be great if this leak could be patched by some brilliant theorist somewhere.<br>
<br>
Luke<br>
<br>
</font></span></span></span></font><blockquote><font size="4"><span style="font-size: 11pt;"><span style="font-size: 14px;"><span style="font-size: 11pt;"><font face="Calibri, Verdana, Helvetica, Arial"> - which makes things tidier - a useful<br>

tip!), I moved to using the state monad and replicateM_ for the first<br>
truncate(endTime/timeStep)-1 elements so that everything but the last result<br>
is thrown away, and a final bind to getEvolution would return the result.<br>
<br>
Now that the code has been modified so that no result is passed back, using<br>
modify and execState, this can be simplified to &quot;replicateM_<br>
truncate(endTime/timeStep)&quot; with no final bind needed. &nbsp;I&#39;ve tried this and<br>
it works fine.<br>
<br>
The key reason for using the Monad was to tell Haskell to discard all but<br>
the current state. &nbsp;If I&#39;m wrong about please let me know, as I don&#39;t want<br>
to be guilty of overcomplicating my algorithm, and more importantly it means<br>
I&#39;m not yet totally grasping the power of Haskell!<br>
<br>
Thanks again,<br>
<font color="#888888"><br>
Phil.<br>
</font><br>
<br>
<br>
<br>
On 13/01/2009 03:13, &quot;David Menendez&quot; &lt;<a href="mailto:dave@zednenem.com" target="_blank">dave@zednenem.com</a>&gt; wrote:<br>
<br>
&gt; On Mon, Jan 12, 2009 at 8:34 PM, Phil &lt;<a href="mailto:pbeadling@mail2web.com" target="_blank">pbeadling@mail2web.com</a>&gt; wrote:<br>
&gt;&gt; Thanks Minh - I&#39;ve updated my code as you suggested. &nbsp;This looks better than<br>
&gt;&gt; my first attempt!<br>
&gt;&gt;<br>
&gt;&gt; Is it possible to clean this up any more? &nbsp;I find:<br>
&gt;&gt;<br>
&gt;&gt; ( (), (Double, Word64) )<br>
&gt;&gt;<br>
&gt;&gt; a bit odd syntactically, although I understand this is just to fit the type<br>
&gt;&gt; to the State c&#39;tor so that we don&#39;t have to write our own Monad longhand.<br>
&gt;<br>
&gt; If you have a function which transforms the state, you can lift it<br>
&gt; into the state monad using &quot;modify&quot;.<br>
&gt;<br>
&gt;&gt; evolveUnderlying :: (Double, Word64) -&gt; (Double, Word64)<br>
&gt;&gt; evolveUnderlying (stock, state) = ( newStock, newState )<br>
&gt;&gt; &nbsp;where<br>
&gt;&gt; &nbsp;&nbsp;&nbsp;newState = ranq1Increment state<br>
&gt;&gt; &nbsp;&nbsp;&nbsp;newStock = stock * exp ( ( ir - (0.5*(vol*vol)) )*timeStep + (<br>
&gt;&gt; vol*sqrt(timeStep)*normalFromRngState(state) ) )<br>
&gt;&gt;<br>
&gt;&gt; getEvolution :: State (Double, Word64) ()<br>
&gt;&gt; getEvolution = modify evolveUnderlying<br>
&gt;<br>
&gt; Now, I don&#39;t know the full context of what you&#39;re doing, but the<br>
&gt; example you posted isn&#39;t really gaining anything from the state monad.<br>
&gt; Specifically,<br>
&gt;<br>
&gt; &nbsp;&nbsp;execState (replicateM_ n (modify f))<br>
&gt; = execState (modify f &gt;&gt; modify f &gt;&gt; ... &gt;&gt; modify f)<br>
&gt; = execState (modify (f . f . ... . f))<br>
&gt; = f . f . ... . f<br>
&gt;<br>
&gt; So you could just write something along these lines,<br>
&gt;<br>
&gt;&gt; mcSimulate :: Double -&gt; Double -&gt; Word64 -&gt; [Double]<br>
&gt;&gt; mcSimulate startStock endTime seedForSeed = fst expiryStock : mcSimulate<br>
&gt;&gt; startStock endTime newSeedForSeed<br>
&gt;&gt; &nbsp;where<br>
&gt;&gt; &nbsp;&nbsp;&nbsp;expiryStock = iterate evolveUnderlying (startStock, ranq1Init seedForSeed)<br>
&gt;&gt; !! truncate (endTime/timeStep)<br>
&gt;&gt; &nbsp;&nbsp;&nbsp;newSeedForSeed = seedForSeed + 246524<br>
&gt;<br>
&gt;<br>
&gt; Coming back to your original question, it is possible to work with<br>
&gt; nested state monad transformers. The trick is to use &quot;lift&quot; to make<br>
&gt; sure you are working with the appropriate state.<br>
&gt;<br>
&gt; get :: StateT s1 (State s2) s1<br>
&gt; put :: s1 -&gt; StateT s1 (State s2) ()<br>
&gt;<br>
&gt; lift get :: StateT s1 (State s2) s2<br>
&gt; lift put :: s2 -&gt; StateT s1 (State s2) ()<br>
&gt;<br>
&gt; A more general piece of advice is to try breaking things into smaller<br>
&gt; pieces. For example:<br>
&gt;<br>
&gt; getRanq1 :: MonadState Word64 m =&gt; m Word64<br>
&gt; getRanq1 = do<br>
&gt; &nbsp;&nbsp;&nbsp;&nbsp;seed &lt;- get<br>
&gt; &nbsp;&nbsp;&nbsp;&nbsp;put (ranq1Increment seed)<br>
&gt; &nbsp;&nbsp;&nbsp;&nbsp;return seed<br>
&gt;<br>
&gt; getEvolution :: StateT Double (State Word64) ()<br>
&gt; getEvolution = do<br>
&gt; &nbsp;&nbsp;&nbsp;&nbsp;seed &lt;- lift getRanq1<br>
&gt; &nbsp;&nbsp;&nbsp;&nbsp;modify $ \stock -&gt; stock * exp ( ( ir - (0.5*(vol*vol)) )*timeStep<br>
&gt; + ( vol*sqrt(timeStep)*normalFromRngState(seed) ) )<br>
&gt;<br>
<br>
_______________________________________________<br>
Haskell-Cafe mailing list<br>
<a href="mailto:Haskell-Cafe@haskell.org" target="_blank">Haskell-Cafe@haskell.org</a><br>
<a href="http://www.haskell.org/mailman/listinfo/haskell-cafe" target="_blank">http://www.haskell.org/mailman/listinfo/haskell-cafe</a><br>
<br>
<br>
</font></span></span></span></font></blockquote></blockquote><span style="font-size: 11pt;"><span style="font-size: 14px;">
</span></span></div></div></div>


</blockquote></div><br>