<HTML>
<HEAD>
<TITLE>Stacking State on State.....</TITLE>
</HEAD>
<BODY>
<FONT SIZE="4"><FONT FACE="Calibri, Verdana, Helvetica, Arial"><SPAN STYLE='font-size:11pt'>Hi,<BR>
<BR>
I&#8217;ve been teaching myself Monads recently &#8211; with some success, but I&#8217;ve hit a snag when I tried to look at transformers. &nbsp;I&#8217;m not sure if the problem is my understanding of transformer use at a theoretical level or if I&#8217;m just getting the syntax wrong.<BR>
<BR>
If I stick a (hopefully) fairly simple example below, I was wondering if people could comment:<BR>
<BR>
Bit of background &#8211; I have no problem using the State Monad and find it very useful for holding the state or say a homemade random number generator. &nbsp;I written several little bits of code like this:<BR>
<BR>
VanDerCorput :: Int-&gt; ( Double, Int )<BR>
VanDerCorput state = ( output, state+1 )<BR>
&nbsp;&nbsp;where<BR>
&nbsp;&nbsp;&nbsp;&nbsp;output = reflect state<BR>
<BR>
getVanDC :: State Int Double<BR>
getVanFC = State VanDerCorput<BR>
<BR>
This is just holding an incremental state and each time it is evaluated the next number in the Van Der Corput sequence in generated &#8211; this is just a quasi random sequence the implementation details of the sequence are irrelevant &#8211; safe to say that the sequence is generated from N=1,2,3,4.....Infinity.<BR>
<BR>
The above example is so trivial it can of course be implemented easily in purely functional code by threading the state as a parameter to a pure function and then mapping that function to an &#8220;iterate (+1) 1&#8221; statement, but that is not the point of the exercise!<BR>
<BR>
The next step of the program is to wrap the above example up in another function which takes the Van Der Corput sequence as input and provides output depending on*<B>it&#8217;s own*</B> state. &nbsp;I&#8217;m passing it to a Box-Muller transform. &nbsp;Very quickly the Box-Muller transform requires TWO inputs from VanDerCourput to produce TWO outputs itself, however we only ever need one at a time, so the Box-Muller transform itself must hold state saying weather it has already saved the 2nd output from a previous call, and thus doesn&#8217;t need to call Van Der Corput this time to produce output &#8211; it just returns its own state. &nbsp;<BR>
<BR>
(P.S. If you know what I&#8217;m doing from a maths point of view please ignore the fact using a 1D Van Der Corput with Box Muller is a very bad idea &#8211; I know this; I&#8217;m keeping the example simple and Haskell orientated!)<BR>
<BR>
In C-like imperative code you&#8217;d could do something like the below &#8211; not that this is massively elegant, but it shows the case-in-point:<BR>
<BR>
Boxmuller()<BR>
{<BR>
&nbsp;&nbsp;&nbsp;&nbsp;// The &#8220;outer&#8221; states of Box Muller<BR>
&nbsp;&nbsp;&nbsp;&nbsp;static bool myState = False;<BR>
&nbsp;&nbsp;&nbsp;&nbsp;static double storedNormal = 0.;<BR>
&nbsp;&nbsp;&nbsp;&nbsp;// Local copy of current state<BR>
&nbsp;&nbsp;&nbsp;&nbsp;bool currentState = myState;<BR>
&nbsp;&nbsp;&nbsp;&nbsp;// State always flips each run<BR>
&nbsp;&nbsp;&nbsp;&nbsp;myState = not myState;<BR>
&nbsp;&nbsp;&nbsp;&nbsp;// If we don&#8217;t have a stored value from a previous run<BR>
&nbsp;&nbsp;&nbsp;&nbsp;if currentState == False<BR>
&nbsp;&nbsp;&nbsp;&nbsp;{<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// Generate two new Van Der Corputs &#8211; this would increment a state in getNextVanDerCorput() twice &#8211; producing different output each time<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;double rand1 = getNextVanDerCorput();<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;double rand2 = getNextVanDerCorput();<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// Store one result for the NEXT run of Boxmuller()<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;storedNormal = SOME_TRANSFORM(rand2);<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// Return the other<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return SOME_TRANSFORM(rand1); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<BR>
&nbsp;&nbsp;&nbsp;&nbsp;}<BR>
&nbsp;&nbsp;&nbsp;&nbsp;// We have a leftover value from a previous run &#8211; get a local copy<BR>
&nbsp;&nbsp;&nbsp;&nbsp;double currentNormal = storedNormal;<BR>
&nbsp;&nbsp;&nbsp;&nbsp;// Reset the stored value to zero<BR>
&nbsp;&nbsp;&nbsp;&nbsp;storedNormal = 0.;<BR>
&nbsp;&nbsp;&nbsp;&nbsp;// Return the local copy of the stored value<BR>
&nbsp;&nbsp;&nbsp;&nbsp;return currentNormal;<BR>
}<BR>
<BR>
getNextVanDerCorput()<BR>
{<BR>
&nbsp;&nbsp;&nbsp;&nbsp;// Starting state<BR>
&nbsp;&nbsp;&nbsp;&nbsp;state int n = 1;<BR>
&nbsp;&nbsp;&nbsp;&nbsp;int currentState = n;<BR>
&nbsp;&nbsp;&nbsp;&nbsp;// Incremented each time we call the function<BR>
&nbsp;&nbsp;&nbsp;&nbsp;++n;<BR>
&nbsp;&nbsp;&nbsp;&nbsp;// Value computed on the internal state of this function<BR>
&nbsp;&nbsp;&nbsp;&nbsp;return SOME_OTHER_TRANSFORM(currentState);<BR>
}<BR>
<BR>
<BR>
Right, hopefully that explains explicitly what I&#8217;m trying to do &#8211; apologies for dropping into C, it&#8217;s easier to explain in code than in words.<BR>
<BR>
It struck me that this could be done using a plain and simple State Monad in Haskell carrying ALL states for both functions around in a tuple. &nbsp;This is pretty ugly tho, and I figure both BoxMuller and VanDerCorput should have their own internal states &#8211; so they can be used as building blocks in other functionality too &#8211; so one big ugly Monad is bad code design, even if it would work for this specific example. &nbsp;Let&#8217;s not go there.<BR>
<BR>
The VanDerCorput building block is just the Monad at the start of this post.<BR>
<BR>
The problem is &#8211; HOW DO I WRAP ANOTHER INDEPENDENT STATE AROUND THIS?<BR>
<BR>
After some googling it looked like the answer may be Monad Transformers. &nbsp;Specifically we could add a StateT transform for our Box Muller state to our VanDerCorput State Monad.<BR>
Google didn&#8217;t yield a direct answer here &#8211; so I&#8217;m not even sure if my thinking is correct, people describe the process of using a transform as &#8216;wrapping one monad in another&#8217; or &#8216;threading one monad into another&#8217;. &nbsp;What we want to do is have some internal state controlled by an independent outer state - &nbsp;this sounds about right to me?<BR>
&nbsp;<BR>
So I started playing around with the code, and got the below to compile.<BR>
<BR>
test :: &nbsp;StateT (Bool,Double) (State Int) Double<BR>
test = do (isStored,normal) &lt;- get<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;let (retNorm,storeNorm) = if isStored<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;then (normal,0) <BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else (n1,n2)<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;where<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;n1 = 2<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;n2 = 3<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;put (not isStored, storeNorm)<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return retNorm<BR>
<BR>
Now this is incomplete and may be even wrong! &nbsp;I&#8217;ll Explain my thinking:<BR>
<BR>
(Bool,Double) is equivalent to myState and storedNormal in the C example<BR>
The last Double is the return value of the BoxMuller Monad<BR>
The (State Int) is supposed to represent the VanDerCorput monad &#8211; but the compiler (GHC 6.10) will only let me specify one parameter with it &#8211; so I&#8217;ve put the state and left the return type to the gods!!.... As I said this isn&#8217;t quite right &#8211; any ideas how to specify the type?<BR>
<BR>
The next few lines get and test the BoxMuller state, this seems to work OK to me, the problem is when I try to look at the STATE OF THE INTERNAL monad. &nbsp;n1 and n2 should evaluate and increment the state of VanDerCorput monad &#8211; but I can&#8217;t get anything to compile here. &nbsp;2 and 3 are just dummy values to make the thing compile so I could debug.<BR>
<BR>
My last gripe is how to actually call this from a pure function &#8211; do I need to use both evalStateT and evalState &#8211; I can&#8217;t see how to initialize both the inner and outer state ?<BR>
<BR>
OK &#8211; I think that&#8217;s more than enough typing, apologies for the war&amp;peace sized post.<BR>
<BR>
Any help muchly muchly appreciated,<BR>
<BR>
Many Thanks,<BR>
<BR>
Phil.<BR>
</SPAN></FONT></FONT>
</BODY>
</HTML>