-6

Please implement the function:

composeApplicative :: (Applicative f) => f (b -> c) -> f (a -> b) -> f (a -> c)

Such that:

(composeApplicative f g) <*> x == f <*> (g <*> x)

Or alternatively, explain why this can not be done?

AJF
  • 11,767
  • 2
  • 37
  • 64
Clinton
  • 22,361
  • 15
  • 67
  • 163
  • 1
    `composeApplicative p q = (.) <$> p <*> q` – isekaijin Jul 12 '15 at 16:27
  • 4
    Is this homework? What have you tried? – jub0bs Jul 12 '15 at 16:28
  • 4
    I'm voting to close this question as off-topic because it likely is homework and the OP has shown no effort. – jub0bs Jul 12 '15 at 16:37
  • Not homework, I tried and got to `(\x -> f <*> g <*> x)` which obviously wasn't what I was looking for. I was trying to make a newtype wrapped applicative function a member of Control.Category. Seeing the answer now it looks obvious but I bashed around for about 20 minutes and got nowhere near it. – Clinton Jul 12 '15 at 16:43
  • 1
    @Clinton Then would it be so difficult to show what you've tried, and state your problem in a way that expresses that you've encountered a problem, not plainly asking for code. You've had downvotes because you've put so little effort into this question. – AJF Jul 12 '15 at 16:46
  • 1
    I didn't think it would help people answering the question nor future people reading it for reference, who wouldn't be interested in my life story. I've asked other questions which I give lots of background when I think it helps people answer the question I have. – Clinton Jul 12 '15 at 16:52
  • 1
    @Clinton You could have at least opened your question with "*I'm trying to make a newtype wrapped applicative function a member of Control.Category*, but [...]". That would have given visitors some context. – jub0bs Jul 12 '15 at 17:05
  • 2
    @Clinton You may say that, but the fact that you've been downvoted indicates that *it's a bad idea*. Please put effort into a question. – AJF Jul 12 '15 at 18:12
  • I am quite fond of this function. I even [wrote a little about it](https://duplode.github.io/posts/applicative-archery.html) a while ago, though you probably won't find it very interesting, as by now you likely have figured it all. – duplode Sep 23 '15 at 07:45

1 Answers1

6

It can be done:

composeApplicative p q = (.) <$> p <*> q

For more information, read the documentation for Applicative functors, more specifically, the composition law. It is effectively a statement that any Applicative instance, composeApplicative f g <*> x must always be equal to f <*> (g <*> x).

As a minor technical note, when doing equational reasoning, the left- and right-hand sides of equations must be separated with a single equals sign (=). The double-equals sign (==) is reserved for decidable runtime equality checks.

isekaijin
  • 19,076
  • 18
  • 85
  • 153
  • "As a minor technical note, when doing equational reasoning, the left- and right-hand sides of equations must be separated with a single equals sign (=). The double-equals sign (==) is reserved for decidable runtime equality checks." This is not a consensus rule; plenty of high-profile Haskellers use `==` for equational reasoning. Not even the GHC documentation follows it consistently; see e.g. [the docs for `Functor` and `Monad`](https://hackage.haskell.org/package/base-4.8.0.0/docs/Control-Monad.html#t:Functor). – Luis Casillas Jul 13 '15 at 18:31
  • @LuisCasillas: Point taken. But I think it's useful to distinguish between equality as a *proposition* (which may or may not be decidable), and *decision procedure* for equality (which in general doesn't exist for arbitrary types). – isekaijin Jul 13 '15 at 19:11