Hi Tom, Not sure how helpful I can be, but since no-one else has replied... On 06/06/06, Thomas Conway <drtomc@gmail.com> wrote:
Consider the following prototypical definitions:
data Node k v = Leaf [(k,v)] | Node [(k,NodePtr k v)]
type NodePtr k v = TVar (Either Int (Node k v))
where the Int is a file offset, or page number, or somesuch.
If an attempt is made during a STM transaction to access a page that is not in memory, I'd like the transaction to "abort" and return the address of the page so that it can be read from disk and the transaction retried.
Now, the code is going to contain quite a frew fragments like the following:
insert p k v = do n <- getNode p case n of Leaf ... ->
I think I want the type of insert to be insert :: NodePtr k v -> k -> v -> Either (STM ()) Int that is, either I get back the transaction, or the page address.
The question is, how do I combine the two monads STM and Either to achieve this cleanly?
Is there a reason why you can't combine the monads the other way around and then use ErrorT monad transformer? I.e. something like this (untested code): type ErrorSTM = ErrorT Int STM insert :: NodePtr k v -> k -> v -> ErrorSTM () getNode :: NodePtr k v -> ErrorSTM (Node k v) getNode = ErrorT . readTVar
I've tried reading a few pages about monad transformers, but it is not evident to me yet how to combine the two. I think it calls for STMT (following the FooT naming convention).
Obviously you can't have a STM transformer because that would allow you to do IO inside an STM transaction. David