[Haskell-cafe] Practical Haskell question.

Jon Cast jcast at ou.edu
Mon Jun 25 11:41:48 EDT 2007

On Monday 25 June 2007, Michael T. Richter wrote:
> On Mon, 2007-25-06 at 01:05 -0500, Jon Cast wrote:
> > What exactly are you trying to do?
> I'm trying to model a transactional system which could fail
> mid-transaction without an easy rollback on conditions which could be
> checked in advance.


> Now if I could just check permissions on each operation 
> the monad emerging is clearer.  Each call in the do block to C, then D
> and finally E would be individually checked for permissions in the Monad
> before the next step could progress.  I can do this.  But if I want to
> change the model to pre-check the privileges (because of performance
> issues or because of resource allocation issues or whatever) I see no
> easy way to do the same thing.  This intrigues me.

Why?  There's no easy or simple way to tell what operations you're going to 
execute in advance.  Take a concrete example:

  s <- readFile "/etc/ourProg"
  let Right xn = flip parse s $ many $ fileName
  flip mapM xn $ \ filename -> readFile xn

Now, you can't possible pre-check this for permissions, because the argument 
to readFile in the fourth line is drawn from an external file; you would have 
to check for permission to read every file in the world.

If your particular permissions issues are indeed independent of the arguments 
to performB, you can use an arrow:

data MyArrow alpha beta = MyArrow (IO Bool) (alpha -> IO beta)
instance Arrow MyArrow where
  arr f = MyArrow (return True) (return . f)
  MyArrow c0 a0 >>> MyArrow c1 a1
     = MyArrow (liftM2 (&&) c0 c1) (\ x -> a0 x >>= a1)

Then you can check the pre-conditions beforehand.  (If you want to see why 
using an arrow helps, try implementing an instance of the class

class Arrow a => ArrowApply a where
  apply :: a (a alpha beta, alpha) beta

for MyArrow.  Can't be done, but apply is built in to monads).

Jonathan Cast

More information about the Haskell-Cafe mailing list