Here&#39;s another angle on part of Jake&#39;s question: <br><br>Can we implement a type &#39;TIVal a&#39; (preferably without unsafePerformIO) with the following interface:<br><br><span style="font-family: courier new,monospace;">&nbsp;&nbsp;&nbsp; newIVal :: STM (TIVal a, a -&gt; STM ()) -- or IO (...)</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">&nbsp;&nbsp;&nbsp; force&nbsp;&nbsp; :: TIVal a -&gt; STM a</span><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">&nbsp;&nbsp;&nbsp; instance Functor&nbsp;&nbsp;&nbsp;&nbsp; IVal</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">&nbsp;&nbsp;&nbsp; instance Applicative IVal</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">&nbsp;&nbsp;&nbsp; instance Monad&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IVal</span><br>
<br>where<br><br>* &#39;newIVal&#39; makes something like an IVar that can be written/defined (just once) with the returned a-&gt;STM().<br>* &#39;force&#39; gets the value, retrying if not yet defined; once force is able to succeed, it always yields the same value.<br>
* &#39;fmap f tiv&#39; becomes defined (force yields a value instead of retrying) when tiv does.&nbsp; Similarly for (&lt;*&gt;) and join.<br>* Forcing &#39;fmap f tiv&#39; more than once results in f being called only once, i.e., the result is cached and reused, as in pure values.&nbsp; Similarly for (&lt;*&gt;) and join.<br>
<br>&nbsp; &nbsp; &nbsp;&nbsp; - Conal<br><br><div class="gmail_quote">On Sat, Apr 26, 2008 at 9:54 AM, Jake Mcarthur &lt;<a href="mailto:jake.mcarthur@gmail.com">jake.mcarthur@gmail.com</a>&gt; wrote:<br><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
I have a problem I&#39;ve been trying to work around using the existing STM API, and so far it seems that I may be unable to do it. For more background, see my blog post at &lt;<a href="http://geekrant.wordpress.com/2008/04/25/stm-caching-need/" target="_blank">http://geekrant.wordpress.com/2008/04/25/stm-caching-need/</a>&gt;. Here, for brevity, I will only describe exactly what I think I need, not what it&#39;s for.<br>

<br>
Say I have a function f :: STM a. The transaction reads from one or more TMVars, performs some computation, and returns the result in the STM monad. Also, in this scenario, it is known that once the TMVars have values, those values will never be changed again (write once, read many, somewhat like IVars before they were removed). Now say I try to use this function as so.<br>

<br>
 &nbsp; &nbsp;liftM2 (,) f f<br>
<br>
So the desired result is a pair in the STM monad where both components are the result from f. The problem I have is that, in the above example, the TMVars are all read twice and the computations are all performed twice, once for each of the components of the resulting pair. In many cases, this may be the correct thing to do because the values of the TMVars may have changed, but what about this case where I _know_ that the values have not been modified?<br>

<br>
What I need is a way to cache the result of f so that future uses of f don&#39;t have to reread from the TMVars, even across multiple transactions, maybe even leading to the eventual garbage collection of the TMVars if they are not used elsewhere.<br>

<br>
Right now I think the only way to do this would be to change the STM implementation slightly and create a new primitive function. If there is a way to do something like this with the current STM API, I would love to hear suggestions. Any ideas?<br>
<font color="#888888">
<br>
- Jake McArthur<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>
</font></blockquote></div><br>