[Haskell-cafe] Re: Practical Haskell question.
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.
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.
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.
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