Hi! I have a class Neuron which has (among others) two functions: attach and deattach. I would like to make a way to call a list/stack/bunch of attach functions in a way that if any of those fail (by exception), deattach for previously already attached values (called attach on them) are deattached (called deattach on them).
I have come up with such way: data Growable where Growable :: Neuron n => LiveNeuron n -> Growable growNeurons :: [IO Growable] -> IO [Growable] growNeurons attaches = growNeurons' attaches [] where growNeurons' [] ls = return ls growNeurons' (a:ats) ls = bracketOnError a (\(Growable l) -> deattach l) (\l -> growNeurons' ats (l:ls)) So I give growNeurons a list of attach actions and it returns a list of attached values ((live)neurons). This works nice, but syntax to use it is ugly: neurons <- growNeurons [ do { a <- attach nerve1; return $ Growable a }, do { a <- attach nerve2; return $ Growable a }, do { a <- attach nerve3; return $ Growable a } ] Types of attach and deattach are (if I simplify): attach :: Nerve n -> IO (LiveNeuron n) deattach :: LiveNeuron n -> IO () Growable is only used so that I can put actions of different type in the list. It seems to me that all this could be wrapped into a monad. So that I would be able to call something like: neurons <- growNeurons' $ do attach nerve1 attach nerve2 attach nerve3 Where I would be allowed to call actions of a special type class which defined also clean-up function (in my case called deattach). And which would be called if there was any exception thrown (and then at the end rethrown). Otherwise, the result would be a list of all computed values. In my case all this in IO monad. So it is possible that evaluation of monad actions would be stacked inside of bracketOnError and in a case of error clean-up functions would be called, otherwise returns a list of results? Mitar _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe