Say I have a data type A which is applicative. (For the sake of the example, we can assume A is Identity).
I now have a new data type that corresponds to the "transformation" from one A to another:
data B a b = B (A a -> A b)
I want to define the trivial Applicative instance for (B a) that produces a new transformation which applies both arguments of <*> to its input and then uses the definition of <*> from the Applicative instance of A.
Formulating this is simple enough:
instance Applicative (B a) where
    pure x = B $ const $ pure x
    (B ftrans) <*> (B xtrans) = B fxtrans 
        where fxtrans inp = let fout = ftrans inp
                                xout = xtrans inp
                            in  fout <*> xout
However, I have the feeling that there should be a straightforward pointfree way of writing this using the fact that (-> a) is an Applicative Functor.
As a sample of what I have in mind, consider my definition of the corresponding Functor instance:
instance Functor (B a) where
    fmap f (B xtrans) = B $ (fmap f) <$> xtrans
Is there a similarly simple way to define the Applicative instance?
One of the neat facts about Applicative is that this class is closed under composition.  You can get the following from Data.Functor.Compose:
newtype Compose f g a = Compose { getCompose :: f (g a) }
instance (Functor f, Functor g) => Functor (Compose f g) where
    fmap f (Compose fga) = Compose (fmap (fmap f) fga)
instance (Applicative f, Applicative g) => Applicative (Compose f g) where
    pure a = Compose (pure (pure a))
    Compose f <*> Compose x = Compose $ (<*>) <$> f <*> x
The Applicative instance for (->) a, which you bring up, is this:
instance Applicative ((->) r) where
    pure = const
    ff <*> fa = \r -> let f = ff r
                          a = fa r
                      in f a
Now, let's expand Compose ff <*> Compose fa :: Compose ((->) (A a)) A b (some steps skipped):
Compose ff <*> Compose fa
    == Compose $ (<*>) <$> ff <*> fa
    == Compose $ \r -> let f = ff r
                           a = fa r
                       in f <*> a
So what you're doing is effectively the composition of (->) (A a) and A.
This, probably?
(B ftrans) <*> (B xtrans) = B ((<*>) <$> ftrans <*> xtrans)
                        To piggy-back on Luis Casillas's answer: If B is literally the data type you're working with, you can simply use Compose ((->) (A a)) A instead. The data constructor would have type Compose :: (A a -> A b) -> Compose ((->) (A a)) A b. 
You can also use a type synonym: type B a = Compose ((->) (A a)) A.
You can have a lot of fun smooshing functors together with Compose, Product, Sum, and friends.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With