concurrent assertions [was re: awaitEval etc]

Colin Runciman
Wed, 19 Feb 2003 17:07:20 +0000

Dean Herrington has mailed me to point out that the metatype is unnecessary:

class Assert a where
  assertW :: MVar a -> a -> a
  assertR :: MVar a -> a

instance Assert a => Assert [a] where
  assertW mv []     = unsafePerformIO $ do putMVar mv []; return []
  assertW mv (x:xs) = unsafePerformIO $ do
                        mvx  <- newEmptyMVar
                        mvxs <- newEmptyMVar
                        putMVar mv (assertR mvx : assertR mvxs)
                        return (assertW mvx x : assertW mvxs xs)
  assertR mv        = unsafePerformIO $ takeMVar mv

When I picked up Claus Reinke's suggestion I divided the problem
into (1) define the writer, and then *separately* (2) define the reader,
which led me to define a type explicitly representing the interface
between the two.  But I missed the opportunity to apply a suitable
deforestation tactic at the end, eliminating this intermediate structure
by shifting reader applications into the writer.

Beside the elimination of the metatype, an additional attraction of
this latest solution is that a single definition of assertR
suffices for all instances.  (Even without automation, defining
assertW instances should be light work given a few handy combinators.)

Thank you Dean!
Colin R