
Hi all, I have a tuple inside a TVar :
type MySTM = TVar (Int,Int)
Whenever I want to edit/read 'a' or 'b' I find myself writing :
editFunction mySTM = do (a',b') <- readTVar mySTM dostuff a' ...
This is boilerplate stuff, so I decided to write some accessors. So far I have :
getA , getB :: MySTM -> STM Int getA mySTM = do (a',b') <- readTVar mySTM return a'
getB mySTM = do (a',b') <- readTVar mySTM return b'
I want to be able to use these accessors like so:
doSomethingWithA mySTM = do case (getA mySTM) of 1 -> doStuff 0 -> doSomethingElse
But getA returns an STM Int, so I still have to do a :
doSomethingWithA = do a' <- (getA mySTM) case a' of 1 -> doStuff 0 -> doSomethingElse
This doesn't really save me a lot of boilerplate. What is the best way of writing a function that just returns my values do I can work with them in the STM monad without unpacking them all the time? Thanks , Deech

But getA returns an STM Int, so I still have to do a :
doSomethingWithA = do a' <- (getA mySTM) case a' of 1 -> doStuff 0 -> doSomethingElse
This doesn't really save me a lot of boilerplate. What is the best way of writing a function that just returns my values do I can work with them in the STM monad without unpacking them all the time?
You can't; that is the whole point. However, there are ways to save some typing. For example, you could use (>>=), which the do-notation desugars to anyway: doSomethingWithA = getA mySTM >>= \a' -> case a' of ... In this case, that doesn't actually save that much, I guess. But you could go much further. For example, if you often find yourself doing case analysis on the value of a, you could write something like caseA :: STM e -> STM e -> STM e caseA act1 act2 = do a' <- (getA mySTM) case a' of 1 -> act1 0 -> act2 Then you could just write 'caseA doStuff doSomethingElse'. And if you wanted something more general than just matching on 1 or 0, you could write (say) caseA' :: [(Int, STM e)] -> STM e And so on. The trick is to abstract out the common patterns in your code. Haskell is really good at this---if you find yourself typing the same boilerplate over and over again, there's (often) a way to abstract out the commonality. -Brent

On Apr 28, 2009, at 01:43 , aditya siram wrote:
I want to be able to use these accessors like so:
doSomethingWithA mySTM = do case (getA mySTM) of 1 -> doStuff 0 -> doSomethingElse
But getA returns an STM Int, so I still have to do a :
doSomethingWithA = do a' <- (getA mySTM) case a' of 1 -> doStuff 0 -> doSomethingElse
This doesn't really save me a lot of boilerplate. What is the best way of writing a function that just returns my values do I can work with them in the STM monad without unpacking them all the time?
Lift your operation into STM with fmap/liftM instead? -- brandon s. allbery [solaris,freebsd,perl,pugs,haskell] allbery@kf8nh.com system administrator [openafs,heimdal,too many hats] allbery@ece.cmu.edu electrical and computer engineering, carnegie mellon university KF8NH
participants (3)
-
aditya siram
-
Brandon S. Allbery KF8NH
-
Brent Yorgey