Merging ST threads
From HaskellWiki
(Difference between revisions)
m (edit formatting of signature) |
m (typo) |
||
| (3 intermediate revisions not shown.) | |||
| Line 49: | Line 49: | ||
</haskell> | </haskell> | ||
| - | Of course, we won't be able to run values of type <hask>ST (s,t) a</hask>, since they violate the <hask>forall | + | Of course, we won't be able to run values of type <hask>ST (s,t) a</hask>, since they violate the <hask>forall</hask> restriction on <hask>runST</hask>. So we need some way to get rid of the tuple: |
<haskell> | <haskell> | ||
| Line 58: | Line 58: | ||
Does this make sense? Is it safe? I doubt it's very useful, but I think it's probably implementable with a bit of hacking inside the implementation of ST. | Does this make sense? Is it safe? I doubt it's very useful, but I think it's probably implementable with a bit of hacking inside the implementation of ST. | ||
-- GaneshSittampalam | -- GaneshSittampalam | ||
| + | |||
| + | [[Category:Code]] | ||
Current revision
In the thread starting at http://www.haskell.org//pipermail/haskell/2004-January/013330.html there is a discussion about temporarily combining two independent monadic state threads. The problem is this: we have a computation that works with one bit of state, say aBool
Int
Bool
Int
start1
start2
Bool
Int
intermediate
(Bool,Int)
end1
end2
start1
start2
intermediate
end1
end2
One solution is to define the individual computations using the StateT monad transformer, and then stack the two monad transformers on top of each other to make the combined one. This is a bit nasty and asymmetric, requiring one computation to be "lifted":
whole
= do
start1
lift start2
intermediate
end1
lift end2Another option is to work with the normal State monad, and to define operations on this monad that "lifts" the state into a tuple:
embedState1 :: State s a -> State (s,t) a embedState2 :: State t a -> State (s,t) a embedState1 (State f) = State (\(s,t) -> let (s',a)=f s in ((s',t),a)) embedState2 (State f) = State (\(s,t) -> let (t',a)=f s in ((s,t'),a)) whole = do embedState1 start1 embedState2 start2 intermediate embedState1 end1 embedState2 end2
forall
The key point is the operation
runST :: (forall s . ST s a) -> a
STRef
If we want to do the above with then ST, then we probably want operations like this:
embedST1 :: ST s a -> ST (s,t) a embedST2 :: ST t a -> ST (s,t) a
ST (s,t) a
forall
runST
finishST1 :: (forall s . ST (s,t) a) -> ST t a finishST2 :: (forall t . ST (s,t) a) -> ST s a
Does this make sense? Is it safe? I doubt it's very useful, but I think it's probably implementable with a bit of hacking inside the implementation of ST.
-- GaneshSittampalam
