Adding (??) into Data.Functor

Edward Kmett ekmett at
Mon Feb 17 23:53:41 UTC 2014

FWIW The reason it is called (??) is to make it look like a placeholder.
foo ?? bar makes a function to replace the ?? placeholder.

It is somewhat more readable than an infixed `flip`.

Given my druthers l'd have kept the name (?) for this in lens rather than
let it devolve to (??), but too many people complained about taking a name
they were already using as (?) was the first operator added to lens without
a word frequency search against hackage first. The number of collisions it
had in practice was rather high.

It was added to lens because a lot of users were asking for variants of a
lot of the lens named combinators that swapped the second and third
arguments, so they could compose more nicely. By adding one name, (??) we
were able to deflect all of those requests.

Given creative use of multiple (??)'s you can use it to shuffle any
argument to last position, but that violates the 'place holder' intuition.

It has the more general type of Stefan Ljungstrand"s version of flip from
lambdabot, because, well, everything in lens tries to be as general as
possible, but the fact that it works for all functors is more or less an
accident that only a few users seem to exploit.

The major uses folks seem to put it to is to shuffle the arguments for
things like runState, etc. to put the monadic action last.

runState ?? myState $ do

is a lot less noisy than surrounding the whole do in quotes or giving a
name to the action

I remain slightly against adding it to a place like Data.Functor because I
don't like randomly stealing operator names and for most applications flip
is more clear as the named combinator conveys intuition about its purpose.

It fits into the lens ecosystem where I'm willing to assume a great deal of
time invested in understanding local idioms, but I feel it is a poor fit
for the larger ecosystem for those reasons.


On Mon, Feb 17, 2014 at 11:21 AM, Twan van Laarhoven <twanvl at>wrote:

> Would (<$$>) be a sensible name? To match (<**>) from Control.Applicative
>   (<$$>) :: Functor f => a -> f (a -> b) -> f b
> I don't really feel the need for such a function, though.
> On a related note, the documentation for (<**>) is pretty bad. It says "A
> variant of <*> with the arguments reversed." but that doesn't make it clear
> that the function is different from `flip (<*>)`.
> Twan
> On 16/02/14 19:51, Dimitri Sabadie wrote:
>> Hi all,
>> I often come up using this snippet:
>> map ($ a) l
>> with
>> l :: [a -> b]
>> In Control.Lens, there’s a nice combinator for that, (??) :
>> l ?? a
>> I think it’d be great to include that in Data.Functor, because it’s a very
>> common use case.
>> _______________________________________________
>> Libraries mailing list
>> Libraries at
> _______________________________________________
> Libraries mailing list
> Libraries at
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <>

More information about the Libraries mailing list