[Haskell-cafe] Caching the Result of a Transaction?

Conal Elliott conal at conal.net
Sat Apr 26 20:18:26 EDT 2008


Here's another angle on part of Jake's question:

Can we implement a type 'TIVal a' (preferably without unsafePerformIO) with
the following interface:

    newIVal :: STM (TIVal a, a -> STM ()) -- or IO (...)
    force   :: TIVal a -> STM a

    instance Functor     IVal
    instance Applicative IVal
    instance Monad       IVal

where

* 'newIVal' makes something like an IVar that can be written/defined (just
once) with the returned a->STM().
* 'force' gets the value, retrying if not yet defined; once force is able to
succeed, it always yields the same value.
* 'fmap f tiv' becomes defined (force yields a value instead of retrying)
when tiv does.  Similarly for (<*>) and join.
* Forcing 'fmap f tiv' more than once results in f being called only once,
i.e., the result is cached and reused, as in pure values.  Similarly for
(<*>) and join.

       - Conal

On Sat, Apr 26, 2008 at 9:54 AM, Jake Mcarthur <jake.mcarthur at gmail.com>
wrote:

> I have a problem I'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 <
> http://geekrant.wordpress.com/2008/04/25/stm-caching-need/>. Here, for
> brevity, I will only describe exactly what I think I need, not what it's
> for.
>
> 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.
>
>    liftM2 (,) f f
>
> 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?
>
> What I need is a way to cache the result of f so that future uses of f
> don'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.
>
> 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?
>
> - Jake McArthur
> _______________________________________________
> Haskell-Cafe mailing list
> Haskell-Cafe at haskell.org
> http://www.haskell.org/mailman/listinfo/haskell-cafe
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20080426/e91f57f7/attachment.htm


More information about the Haskell-Cafe mailing list