[Haskell-cafe] Re: Practical Haskell question.

2007-06-25 Thread apfelmus
Wouter Swierstra wrote:
 I don't think you really want arrows here. The right idiom is
 applicative functors (see Control.Applicative). You could then write the
 above as:
 
 calculateStuff $ x * y * z

I think you mean

 calculateStuff $ performActionA * performActionB * performActionC


Regards,
apfelmus

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Re: Practical Haskell question.

2007-06-25 Thread apfelmus
Benja Fallenstein wrote:
 Hi Peter,
 
 2007/6/25, peterv [EMAIL PROTECTED]:
 I'm baffled. So using the Arrow abstraction (which I don't know yet) would
 solve this problem? How can (perfectActionB x) be checked with without
 ever executing performActionA which evaluates to x? This can only be done
 when x is a constant expression no?
 
 Arrows separate the action -- 'performActionB' -- from the argument --
 'x', so you can look at the action before you have to compute the
 argument to it. Of course, this means that you can no longer compute
 the action from the argument -- that is, 'if x then performActionB
 else performActionC' is something you can't directly do; you have to
 use a choice primitive instead, which explicitly says use one of
 these two arrows depending on what value this argument is, which then
 lets the library check these two arrows before actually applying them
 to an argument.

Well, arrows can't solve the problem as well iff performActionB may be
permissible _depending_ on x, i.e.

  performActionB x = if x then pickFlowers else eraseHardDrive

There's no way to check whether performActionB is permissible for a
given run without executing performActionA for the permissibility of B
depends on the output of A.

But I think that Michael had conditions in mind that can be checked
before executing any of the actions. Of course, the simplest way is to
check manually:

 do
   if i'mRoot
 then do
   x - performActionA
   y - performActionB
   z - performActionC
   return $ calculateStuff x y z
 else
   cry gimme root

but you could still write performActionA somewhere without having
checked/established root permission. This can be solved by using a
custom monad

  newtype Sudo a = Sudo { act :: IO a }
   deriving (Functor,Monad,MonadIO)

which has the following operations

  performActionA :: Sudo Int
  performActionB :: Sudo String
  etc.

and that can only be run with

  sudo :: Sudo a - IO (Either String a)
  sudo m = do
b - makeMeRoot
if b
  then liftM Right $ act m
  else return $ Left Could not become Root

Putting Sudo into a module and making it abstract ensures that you can't
break the invariant that stuff of type Sudo a will either be run as
root or not at all.

Regards,
apfelmus

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Re: Practical Haskell question.

2007-06-25 Thread apfelmus
Michael T. Richter wrote:
 It looked to me like there were people arguing about whether the x
 returned from one action was going to be used in the next action.

 Let me try and rephrase the question.  :)

 [rephrase]

Yes, and that's an important constellation your problem description does
not consider. Take the code

 doStuff():
 if checkPossible( ?? ):
 x - A
 if x
   then B
   else C
 else:
 exception Preconditions not met

What should be put as argument into checkPossible? checkPossible([opA,
opB, opC])? What if x happens to be always true and C is never run? What
if B is possible if and only if C is not?

Sequencing actions is not just putting them in a row, but also feeding
the results of one action to the next ones. You have to restrict this in
some way to make your goal possible.

 And can it be done somehow in Haskell?

Most likely, and Haskell even tells you when your approach doesn't work
without further specification :)

Regards,
apfelmus

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: Practical Haskell question.

2007-06-25 Thread Henning Thielemann

On Mon, 25 Jun 2007, apfelmus wrote:

 Michael T. Richter wrote:
  It looked to me like there were people arguing about whether the x
  returned from one action was going to be used in the next action.
 
  Let me try and rephrase the question.  :)
 
  [rephrase]

 Yes, and that's an important constellation your problem description does
 not consider.

If Michael had asked for code that has to be executed _after_ the actual
actions, say for cleanup, this would have been simple. If he knows that
the performAction commands don't use results of former actions, then the
Applicative approach described earlier in this thread would work, though
without 'do' notation.
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe