1

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?

Jules
  • 14,841
  • 9
  • 83
  • 130
  • 1
    [This?](http://hayoo.fh-wedel.de/?query=Applicative+f+%3D%3E+f+%28a+-%3E+b%29+-%3E+a+-%3E+f+b) – Alec Apr 11 '17 at 03:00
  • 2
    Note that `doSomething` isn't saving you very much typing. It just replaces the calls to `<*>` and `pure` with a call to `doSomething`. And importantly, it doesn't scale to 2+ argument functions, especially if you want to allow some of the arguments to be pure and some to be wrapped. I think it's better for readability to just write `f <*> pure x` and `f <*> x <*> pure y`. – amalloy Apr 11 '17 at 03:06
  • @Alec - yes, that seems to be what I'm looking for. Wonder why hoogle didn't find it... – Jules Apr 11 '17 at 03:15
  • @amolloy - `doSomething` is intended as an example of what I'm doing in an application-specific context, rather than a general purpose function I'm trying to define. More specifically, what I'm trying to do right now is define a combinator function that works on a family of data constructors that all have the same first argument type, which automatically supplies the appropriate value to that argument, returning the result in a monad (because the value to supply to that argument is supplied by a monad). – Jules Apr 11 '17 at 03:16
  • 1
    @Jules The question in your OP and the question in your comment are entirely different questions. More importantly, the latter question is far too vague to get a useful answer here. You should state what you want to accomplish more concretely. – user2407038 Apr 11 '17 at 04:14
  • @user2407038 - what I want is an operator that is equivalent to `a <*> (pure b)`; the code in my question is an example of the kind of code I would be using this operator in. Obviously I can define this myself, but if there is a standard way of doing this I would like to use that instead. – Jules Apr 11 '17 at 04:18
  • @Jules The standard way of writing `a <*> pure b` is `a <*> pure b`. This is because `a` and `b` are abstract, unspecified things - you have only told us that `a :: F x` for some `Applicative F`. There is no such general operator for `Applicative`, because there are an absurd number of such general operators for `Applicative`, because `Applicative` itself is so general. If you state what you want to achieve more concretely, then your question may actually have an answer. – user2407038 Apr 11 '17 at 04:29
  • @user2407038 - my aim is simply to simplify the use of code that returns a data constructor wrapped in a monad, as described in the comment above. Basically, I have a lot of code in my application that, if I don't define such an operator, is going to result in literally hundreds of "pure" invocations that are essentially noise. I want to remove them, as I described in the question. As mentioned in above comments, `a` is a data constructor wrapped in a monad, and `b` is an argument to that constructor (of unspecified type because it could be any of a number of types). – Jules Apr 11 '17 at 05:30

2 Answers2

6

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"
Zeta
  • 103,620
  • 13
  • 194
  • 236
3

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.)

duplode
  • 33,731
  • 7
  • 79
  • 150