proposal #2461: add Traversable
generalizations?of?mapAccumL?and mapAccumR
Conor McBride
conor at strictlypositive.org
Mon Jul 28 05:54:36 EDT 2008
Hi
On 28 Jul 2008, at 09:48, Michael Karcher wrote:
> Conor McBride <conor at strictlypositive.org> 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
More information about the Libraries
mailing list