Reputation: 15199
If I have a function (e.g. of type a -> b
) wrapped in an Applicative
and a value that can be applied to it (i.e. a value of type a
in the above example), I can apply it as follows:
doSomething :: Applicative f => f (a -> b) -> a -> f b
doSomething wrappedFn arg = wrappedFn <*> (pure arg)
I find myself doing this a lot. Is there a standard, predefined operator somewhere that will make this code more concise, or do I need to define one myself? If the latter, is there a conventional name for it?
Upvotes: 1
Views: 159
Reputation: 105876
Is there a standard, predefined operator somewhere that will make this code more concise…?
No.
… or do I need to define one myself?
Yes (unless you want to import external packages).
If the latter, is there a conventional name for it?
It's called (??)
in lens, and some have other names. According to lens, it's a generalized variant of flip
, which makes sense:
flip :: (a -> b -> c) -> b -> a -> c
(??) :: Functor f => f (b -> c) -> b -> f c
Substitute f
with ((->) a
and you get flip
from (??)
. Therefore, you can call it generalized flip.
By the way, you don't need Applicative
. Functor
is enough:
gFlip :: Functor f => f (a -> b) -> a -> f b
gFlip f x = fmap ($x) f
Some examples:
ghci> gFlip [(+ 1),(* 2)] 2
[3, 4]
ghci> gFlip (++) "world" "hello"
"helloworld"
Upvotes: 6
Reputation: 34378
There actually is a moderately well-known version of this operator, namely, (??)
from lens:
(??) :: Functor f => f (a -> b) -> a -> f b
Note the Functor
constraint. It turns out that Applicative
isn't necessary, as it can be defined as \f x -> ($ x) <$> f
.
The canonical use case for (??)
is with the function functor, as an infix flip
:
GHCi> execState ?? [] $ modify (1:)
[1]
In the general case, it does exactly what you want:
GHCi> [negate] ?? 3
[-3]
(Personally, I still find [negate] <*> pure 3
more readable, but YMMV.)
Upvotes: 3