sevo
sevo

Reputation: 4609

What are Applicative left and right star sequencing operators expected to do?

I looked up the implementation and it's even more mysterious:

-- | Sequence actions, discarding the value of the first argument.
(*>) :: f a -> f b -> f b
a1 *> a2 = (id <$ a1) <*> a2
-- This is essentially the same as liftA2 (flip const), but if the
-- Functor instance has an optimized (<$), it may be better to use
-- that instead. Before liftA2 became a method, this definition
-- was strictly better, but now it depends on the functor. For a
-- functor supporting a sharing-enhancing (<$), this definition
-- may reduce allocation by preventing a1 from ever being fully
-- realized. In an implementation with a boring (<$) but an optimizing
-- liftA2, it would likely be better to define (*>) using liftA2.

-- | Sequence actions, discarding the value of the second argument.
(<*) :: f a -> f b -> f a
(<*) = liftA2 const

I don't even understand why does <$ deserve a place in a typeclass. It looks like there is some sharing-enhancig effect which fmap . const might not have and that a1 might not be "fully realized". How is that related to the meaning of Applicative sequencing operators?

Upvotes: 3

Views: 312

Answers (1)

Rein Henrichs
Rein Henrichs

Reputation: 15605

These operators sequence two applicative actions and provide the result of the action that the arrow points to. For example,

> Just 1 *> Just 2
Just 2

> Just 1 <* Just 2
Just 1

Another example in writing parser combinators is

brackets p = char '(' *> p <* char ')'

which will be a parser that matches p contained in brackets and gives the result of parsing p.

In fact, (*>) is the same as (>>) but only requires an Applicative constraint instead of a Monad constraint.

I don't even understand why does <$ deserve a place in a typeclass.

The answer is given by the Functor documentation: (<$) can sometimes have more efficient implementations than its default, which is fmap . const.

How is that related to the meaning of Applicative sequencing operators?

In cases where (<$) is more efficient, you want to maintain that efficiency in the definition of (*>).

Upvotes: 7

Related Questions