
Hi On 28 Jul 2008, at 09:48, Michael Karcher wrote:
Conor McBride
wrote: Michael wrote
David wrote (with patch applied): [...] (Backward f) <*> (Backward a) = Backward (a <**> f) According to the haddock of Control.Applicative, this line is semantically equivalent to Backward f <*> Backward a = Backward (f <*> a) I'm not saying the haddock is entirely clear, but it certainly doesn't necessitate the interpretation you're making.
OK, right. But the text "A variant of <*> with the arguments reversed" at least sounds like "<**> = flip <*>", which obviously is untrue then.
Yes, perhaps "A variant of <*> where the argument is computed before the function" might be more helpful. I can't help thinking that the definition might be the best documentation here.
Appearances can be deceptive, so why not actually try it? I tried it, but too pure. I just checked whether some arguments are somehow reversed, but didn't pay care to the effects:
*Main> runBackward $ (pure (++)) <*> (pure "Hello") <*> (pure " World") "Hello World" *Main> runBackward $ (pure (^)) <*> (pure 1) <*> (pure 2) 1
Indeed, the relevant laws guarantee that you need at least two effectful subcomputations to distinguish an applicative functor from its Backward companion. Hence
*Backward> runBackward $ traverse (Backward . print) ["bong", "bing"] "bing" "bong" [(),()]
In contrast with monads, the applicative interface does not offer the ability to make the choice of one computation depend on the value of another Yeah, right. That's the point of Applicative, if I remember the paper correctly.
Yes, it's a weaker demand, hence the resulting combinators are potentially more useful. Often, it's all you need. Cheers Conor