
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