On Mon, 25 Jun 2007, Daniil Elovkov wrote: > 2007/6/25, Michael T. Richter <[EMAIL PROTECTED]>: > > > > Now I've got a situation I can't figure out how to resolve. I want to > > have a set of actions which are executed sequentially, but which, before I > > even start to execute the first one, have been inspected for legality > > and/or plausibility. Consider this kind of sequence: > > > > do > > x <- performActionA > > y <- performActionB > > z <- performActionC > > return $ calculateStuff x y z > > > > Now obviously this is going to be in a monad of some kind. Were this a > > regular, run-of-the-mill program I'd just use the IO monad. But what I > > want to do instead is, before executing any of the perform* functions, > > check that the actions desired are actually permitted (or possible) given a > > set of circumstances. For example let's say it's a permissions issue and > > performActionB can only be done if I'm root. If I'm not root I don't want > > performActionA done because I can't complete the transaction. (Maybe > > ActionA is non-reversible, say.) Or let's say this is code that's > > accessing databases on the network. If the network link to C can't be > > established, I don't want to screw around with A and B's links at all -- > > it's too expensive, too time-consuming or whatever. > > > > Were I programming this in C, C++, Python, Ruby, etc. I could do this in > > my sleep. Functions are addresses (C/C++) or objects with an ID > > (Python/Ruby) so it's possible to take them and do some kind of check based > > on identities before executing things (although the scaffolding around this > > would be nontrivial in any of these languages except, possibly, Ruby). > > Functions in Haskell don't have this property, however, so I can't figure > > out what I'd do to perform similar work. I'm sure there's a way to do it, > > but I just can't see it. > > > Hello, I would suggest defining your own data type an instance of > monad. The sense of it would be 'sequantial IO operations which you > can do some checks on'. > > It would have some flags and properties along with the IO computation > itself. Operations (>>) and (>>=) would construct more complex > computations from simple ones, and since your data type is not opaque > to you, you could inspect those complex computations for properties, > too. Including synergetic ones, like 'this is never done, after that > has been invoked...'
This is easier said than done. Imagine all performActions contain their checks somehow. Let performActionB take an argument. > do > x <- performActionA > y <- performActionB x > z <- performActionC > return $ calculateStuff x y z Now performActionB and its included check depend on x. That is, the check relies formally on the result of performActionA and thus check B must be performed after performActionA. _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe