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