Indeed it does:
λ :i Applicative
class Functor f => Applicative (f :: * -> *) where
At the same time:
fmap f x = pure f <*> x
— by the laws of Applicative we can define fmap from pure & <*>.
I don't get why I should tediously define fmap every time I want an Applicative if, really, fmap can be automatically set up in terms of pure and <*>.
I gather it would be necessary if pure or <*> were somehow dependent on the definition of fmap but I fail to see why they have to.
While fmap can be derived from pure and <*>, it is generally not the most efficient approach. Compare:
fmap :: (a -> b) -> Maybe a -> Maybe b
fmap f Nothing = Nothing
fmap f (Just x) = Just (f x)
with the work done using Applicative tools:
fmap :: (a -> b) -> Maybe a -> Maybe b
-- inlining pure and <*> in: fmap f x = pure f <*> x
fmap f x = case (Just f) of
Nothing -> Nothing
Just f' -> case x of
Nothing -> Nothing
Just x' -> Just (f' x')
Pointlessly wrapping something up in a constructor just to do a pattern-match against it.
So, clearly it is useful to be able to define fmap independently of the Applicative functions. That could be done by making a single typeclass with all three functions, using a default implementation for fmap that you could override. However, there are types that make good Functor instances but not good Applicative instances, so you may need to implement just one. Thus, two typeclasses.
And since there are no types with Applicative instances but without Functor instances, you should be able to treat an Applicative as though it were a Functor, if you like; hence the extension relationship between the two.
However, if you tire of implementing Functor, you can (in most cases) ask GHC to derive the only possible implementation of Functor for you, with
{-# LANGUAGE DeriveFunctor #-}
data Boring a = Boring a deriving Functor
While there are proposals to make it's easier https://ghc.haskell.org/trac/ghc/wiki/IntrinsicSuperclasses the "default instances" problem itself is very difficult.
One challenge is how to deal with common superclasses:
fmap f x = pure f <*> x -- using Applicative
fmap f x = runIdentity (traverse (Identity . f) x) -- using Traversable
fmap f x = x >>= (return . f) -- using Monad
Which one to pick?
So the best we can do now is to provide fmapDefault (as Data.Traversable) does; or use pure f <*> x; or fmapRep from Data.Functor.Rep when applicable.
Related
Exercise 5 of the Haskell Typeclassopedia Section 3.2 asks for a proof or counterexample on the statement
The composition of two Functors is also a Functor.
I thought at first that this was talking about composing the fmap methods defined by two separate instances of a Functor, but that doesn't really make sense, since the types wouldn't match up as far as I can tell. For two types f and f', the types of fmap would be fmap :: (a -> b) -> f a -> f b and fmap :: (a -> b) -> f' a -> f' b, and that doesn't really seem composable. So what does it mean to compose two Functors?
A Functor gives two mappings: one on the type level mapping types to types (this is the x in instance Functor x where), and one on the computation level mapping functions to functions (this is the x in fmap = x). You are thinking about composing the computation-level mapping, but should be thinking about composing the type-level mapping; e.g., given
newtype Compose f g x = Compose (f (g x))
can you write
instance (Functor f, Functor g) => Functor (Compose f g)
? If not, why not?
What this is talking about is the composition of type constructors like [] and Maybe, not the composition of functions like fmap. So for example, there are two ways of composing [] and Maybe:
newtype ListOfMabye a = ListOfMaybe [Maybe a]
newtype MaybeOfList a = MaybeOfList (Maybe [a])
The statement that the composition of two Functors is a Functor means that there is a formulaic way of writing a Functor instance for these types:
instance Functor ListOfMaybe where
fmap f (ListOfMaybe x) = ListOfMaybe (fmap (fmap f) x)
instance Functor MaybeOfList where
fmap f (MaybeOfList x) = MaybeOfList (fmap (fmap f) x)
In fact, the Haskell Platform comes with the module Data.Functor.Compose that gives you a Compose type that does this "for free":
import 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 x) = Compose (fmap (fmap f) x)
Compose is particularly useful with the GeneralizedNewtypeDeriving extension:
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
newtype ListOfMaybe a = ListOfMaybe (Compose [] Maybe a)
-- Now we can derive Functor and Applicative instances based on those of Compose
deriving (Functor, Applicative)
Note that the composition of two Applicatives is also an Applicative. Therefore, since [] and Maybe are Applicatives, so is Compose [] Maybe and ListOfMaybe. Composing Applicatives is a really neat technique that's slowly becoming more common these days, as an alternative to monad transformers for cases when you don't need the full power of monads.
The composition of two functions is when you put one function inside another function, such as
round (sqrt 23)
This is the composition of the two functions round and sqrt. Similarly, the composition of two functors is when you put one functor inside another functor, such as
Just [3, 5, 6, 2]
List is a functor, and so is Maybe. You can get some intuition for why their composition also is a functor if you try to figure out what fmap should do to the above value. Of course it should map over the contents of the inner functor!
It really helps to think about the categorical interpretation here, a functor F: C -> D takes objects (values) and morphisms (functions) to objects and morphisms from a category C to objects and morphisms in a category D.
For a second functor G : D -> E the composition of functors G . F : C -> E is just taking the codomain of F fmap transformation to be the domain of the G fmap transformation. In Haskell this is accomplished with a little newtype unwrapping.
import Data.Functor
newtype Comp f g a = Comp { unComp :: f (g a) }
compose :: f (g a) -> Comp f g a
compose = Comp
decompose :: Comp f g a -> f (g a)
decompose = unComp
instance (Functor f, Functor g) => Functor (Comp f g) where
fmap foo = compose . fmap (fmap foo) . decompose
Control.Monad.Free implements a free monad as:
data Free f a = Pure a | Free (f (Free f a))
instance Functor f => Functor (Free f) where
fmap f = go where
go (Pure a) = Pure (f a)
go (Free fa) = Free (go <$> fa)
I am having a lot of trouble understanding the second go line, especially in the context of descriptions of what a free monad is. Can somenoe please describe how this works and why it makes Free f a a free monad?
At this point, you're just making Free a functor rather than a monad. Of course, to be a monad, it has to be a functor as well!
I think it would be a little easier to think about if we rename the Free constructor to avoid confusion:
data Free f a = Pure a | Wrap (f (Free f a))
Now let's look at the structure of what we're building up. For the Pure case, we just have a value of type a. For the Wrap case, we have another Free f a value wrapped in the f functor.
Let's ignore the constructors for a second. That is, if we have Wrap (f (Pure a)) let's think of it as f a. This means that the structure we're building up is just f--a functor--applied repeatedly some number of times. Values of this type will look something like: f (f (f (f (f a)))). To make it more concrete, let f be [] to get: [[[[[a]]]]]. We can have as many levels of this as we want by using the Wrap constructor repeatedly; everything ends when we use Pure.
Putting the constructors back in, [[a]] would look like: Wrap [Wrap [Pure a]].
So all we're doing is taking the Pure value and repeatedly applying a functor to it.
Given this structure of a repeatedly applied functor, how would we map a function over it? For the Pure case--before we've wrapped it in f--this is pretty trivial: we just apply the function. But if we've already wrapped our value in f at least once, we have to map over the outer level and then recursively map over all the inner layers. Put another way, we have to map mapping over the Free monad over the functor f.
This is exactly what the second case of go is doing. go itself is just fmap for Free f a. <$> is fmap for f. So what we do is fmap go over f, which makes the whole thing recursive.
Since this mapping function is recursive, it can deal with an arbitrary number of levels. So we can map a function over [[a]] or [[[[a]]]] or whatever. This is why we need to fmap go when go is fmap itself--the important difference being that the first fmap works for a single layer of f and go recursively works for the whole Free f a construction.
I hope this cleared things up a bit.
To tell you the truth, I usually just find it easier not to read the code in these simpler functions, but rather to read the types and then write the function myself. Think of it as a puzzle. You're trying to construct this:
mapFree :: Functor f => (a -> b) -> Free f a -> Free f b
So how do we do it? Well, let's take the Pure constructor first:
mapFree f (Pure a) = ...
-- I like to write comments like these while using Haskell, then usually delete
-- them by the end:
--
-- f :: a -> b
-- a :: a
With the two type comments in there, and knowing the type of Pure, you should see the solution right away:
mapFree f (Pure a) = Pure (f a)
Now the second case:
mapFree f (Free fa) = ...
-- f :: a -> b
-- fa :: Functor f => f (Free f a)
Well, since f is a Functor, we can actually use mapFree to apply mapFree f to the inner component of f (Free f a). So we get:
mapFree f (Free fa) = Free (fmap (mapFree f) fa)
Now, using this definition as the Functor f => Functor (Free f) instance, we get:
instance Functor f => Functor (Free f) where
fmap f (Pure a) = Pure (f a)
fmap f (Free fa) = Free (fmap (fmap f) fa)
With a bit of work, you can verify that the definition we just arrived at here is the same thing as the one you're puzzling over. (As others have mentioned, (<$>) (defined in Control.Applicative) is just a synonym for fmap.) You may still not understand it, but you managed to write it, which for types as abstract as these is very often good enough.
As for understanding it, though, the thing that helps me is the following: think of a Free monad as a sort of list-like structure, with Pure as [] and Free as (:). From the definition of the type you should see this: Pure is the base case, and Free is the recursive case. What the fmap instance is doing is "pushing" the mapped function to the bottom of this structure, to where the Pure lives.
Since I am confused myself, I answer with a question...could this be a correct substitution (relying on Tikhon's Wrap clarification)?
...
fmap g = go where
go (Pure a) = Pure (g a)
go (Wrap fa) = Wrap (go <$> fa)
Substituting "fmap g" for "go", and "fmap" for "<$>" (since "<$>" is infix,
we flip "go" and "<$>"):
fmap g (Pure a) = Pure (g a)
fmap g (Wrap fa) = Wrap (fmap (fmap g) fa)
Substituting "f (Free f a)" for "fa" in the last line (from the first data
declaration):
fmap g (Wrap fa) = Wrap ( fmap (fmap g) (f (Free f a)) )
= Wrap ( f ( fmap g (Free f a) ) )
= wrap ( f (Pure (g a) ) ) --if Free f a is Pure
or
= Wrap ( f ( fmap g (Wrap fa') ) ) --if Free f a is Wrap
The last line includes the recursion "fmap g (Wrap fa')", which would continue
unless Pure is encountered.
Monads are known to be theoretically a subset of functors and specifically applicative functors, even though it's not indicated in Haskell's type system.
Knowing that, given a monad and basing on return and bind, how to:
derive fmap,
derive <*> ?
Well, fmap is just (a -> b) -> f a -> f b, i.e. we want to transform the monadic action's result with a pure function. That's easy to write with do notation:
fmap f m = do
a <- m
return (f a)
or, written "raw":
fmap f m = m >>= \a -> return (f a)
This is available as Control.Monad.liftM.
pure :: a -> f a is of course return. (<*>) :: f (a -> b) -> f a -> f b is a little trickier. We have an action returning a function, and an action returning its argument, and we want an action returning its result. In do notation again:
mf <*> mx = do
f <- mf
x <- mx
return (f x)
Or, desugared:
mf <*> mx =
mf >>= \f ->
mx >>= \x ->
return (f x)
Tada! This is available as Control.Monad.ap, so we can give a complete instance of Functor and Applicative for any monad M as follows:
instance Functor M where
fmap = liftM
instance Applicative M where
pure = return
(<*>) = ap
Ideally, we'd be able to specify these implementations directly in Monad, to relieve the burden of defining separate instances for every monad, such as with this proposal. If that happens, there'll be no real obstacle to making Applicative a superclass of Monad, as it'll ensure it doesn't break any existing code. On the other hand, this means that the boilerplate involved in defining Functor and Applicative instances for a given Monad is minimal, so it's easy to be a "good citizen" (and such instances should be defined for any monad).
fmap = liftM and (<*>) = ap. Here are links to the source code for liftM and ap. I presume you know how to desugar do notation.
When reading stuff on Haskell, I sometimes come across the adjective "applicative", but I have not been able to find a sufficiently clear definition of this adjective (as opposed to, say, Haskell's Applicative class). I would like to learn to recognize a piece of code/algorithm/data structure, etc. that is "applicative", just like I can recognize one that is "recursive". Some contrasting examples of "applicative" vs. whatever the term intends to draw a distinction from (which I hope is something more meaningful in its own right than "non-applicative") would be much appreciated.
Edit: for example, why was the word "applicative" chosen to name the class, and not some other name? What is it about this class that makes the name Applicative such a good fit for it (even at the price of its obscurity)?
Thanks!
It's not clear what "applicative" is being used to mean without knowing the context.
If it's truly not referring to applicative functors (i.e. Applicative), then it's probably referring to the form of application itself: f a b c is an applicative form, and this is where applicative functors get their name from: f <$> a <*> b <*> c is analogous. (Indeed, idiom brackets take this connection further, by letting you write it as (| f a b c |).)
Similarly, "applicative languages" can be contrasted with languages that are not primarily based on the application of function to argument (usually in prefix form); concatenative ("stack based") languages aren't applicative, for instance.
To answer the question of why applicative functors are called what they are in depth, I recommend reading
Applicative programming with effects; the basic idea is that a lot of situations call for something like "enhanced application": applying pure functions within some effectful context. Compare these definitions of map and mapM:
map :: (a -> b) -> [a] -> [b]
map _ [] = []
map f (x:xs) = f x : map f xs
mapM :: (Monad m) => (a -> m b) -> [a] -> m [b]
mapM _ [] = return []
mapM f (x:xs) = do
x' <- f x
xs' <- mapM f xs
return (x' : xs')
with mapA (usually called traverse):
mapA :: (Applicative f) => (a -> f b) -> [a] -> f [b]
mapA _ [] = pure []
mapA f (x:xs) = (:) <$> f x <*> mapA f xs
As you can see, mapA is much more concise, and more obviously related to map (even more so if you use the prefix form of (:) in map too). Indeed, using the applicative functor notation even when you have a full Monad is common in Haskell, since it's often much more clear.
Looking at the definition helps, too:
class (Functor f) => Applicative f where
pure :: a -> f a
(<*>) :: f (a -> b) -> f a -> f b
Compare the type of (<*>) to the type of application: ($) :: (a -> b) -> a -> b. What Applicative offers is a generalised "lifted" form of application, and code using it is written in an applicative style.
More formally, as mentioned in the paper and pointed out by ertes, Applicative is a generalisation of the SK combinators; pure is a generalisation of K :: a -> (r -> a) (aka const), and (<*>) is a generalisation of S :: (r -> a -> b) -> (r -> a) -> (r -> b). The r -> a part is simply generalised to f a; the original types are obtained with the Applicative instance for ((->) r).
As a practical matter, pure also allows you to write applicative expressions in a more uniform manner: pure f <*> effectful <*> pure x <*> effectful as opposed to (\a b -> f a x b) <$> effectful <*> effectful.
On a more fundamental level one could say that "applicative" means working in some form of the SK calculus. This is also what the Applicative class is about. It gives you the combinators pure (a generalization of K) and <*> (a generalization of S).
Your code is applicative when it is expressed in such a style. For example the code
liftA2 (+) sin cos
is an applicative expression of
\x -> sin x + cos x
Of course in Haskell the Applicative class is the main construct for programming in an applicative style, but even in a monadic or arrowic context you can write applicatively:
return (+) `ap` sin `ap` cos
arr (uncurry (+)) . (sin &&& cos)
Whether the last piece of code is applicative is controversial though, because one might argue that applicative style needs currying to make sense.
I've been trying to "learn me a Haskell" through the online book LYAH.
The author describes the behaviour of Functors of the Applicative type as sort of having the ability to extract a function from one functor and mapping it over a second functor; this is through the <*> function declared for the Applicative type class:
class (Functor f) => Applicative f where
pure :: a -> f a
(<*>) :: f (a -> b) -> f a -> f b
As a simple example, the Maybe type is an instance of Applicative under the following implementation:
instance Applicative Maybe where
pure = Just
Nothing <*> _ = Nothing
(Just f) <*> something = fmap f something
An example of the behaviour mentioned previously:
ghci> Just (*2) <*> Just 10 -- evaluates to Just 20
so the <*> operator "extracts" the (*2) function from the first operand and maps it over the second operand.
Now in Applicative types, both operands of <*> are of the same type, so I thought as an exercise why not try implementing a generalisation of this behaviour, where the two operands are Functors of different types, so I could evaluate something like this:
Just (2*) <*:*> [1,2,3,4] -- should evaluate to [2,4,6,8]
So this is what I came up with:
import Control.Applicative
class (Applicative f, Functor g) => DApplicative f g where
pure1 :: a -> f a
pure1 = pure
(<*:*>) :: f ( a -> b ) -> g a -> g b -- referred below as (1)
instance DApplicative Maybe [] where -- an "instance pair" of this class
(Just func) <*:*> g = fmap func g
main = do putStrLn(show x)
where x = Just (2*) <*:*> [1,2,3,4] -- it works, x equals [2,4,6,8]
Now, although the above works, I'm wondering if we can do better; is it possible to give a default implementation for <*:*> that can be applied to a variety of f & g pairs, in the declaration for DApplicative f g itself? And this leads me to the following question: Is there a way to pattern match on constructors across different data types?
I hope my questions make some sense and I'm not just spewing nonsense (if I am, please don't be too harsh; I'm just an FP beginner up way past his bedtime...)
This does make sense, but it ends up being not particularly useful in its current form. The problem is exactly what you've noticed: there is no way to provide a default which does sensible things with different types, or to generally convert from f to g. So you'd have a quadratic explosion in the number of instances you'd need to write.
You didn't finish the DApplicative instance. Here's a full implementation for Maybe and []:
instance DApplicative Maybe [] where -- an "instance pair" of this class
(Just func) <*:*> g = fmap func g
Nothing <*:*> g = []
This combines the behaviors of both Maybe and [], because with Just it does what you expect, but with Nothing it returns nothing, an empty list.
So instead of writing DApplicative which takes two different types, what if you had a way of combining two applicatives f and g into a single type? If you generalize this action, you could then use a standard Applicative with the new type.
This could be done with the standard formulation of Applicatives as
liftAp :: f (g (a -> b)) -> f (g a) -> f (g b)
liftAp l r = (<*>) <$> l <*> r
but instead let's change Maybe:
import Control.Applicative
newtype MaybeT f a = MaybeT { runMaybeT :: f (Maybe a) }
instance (Functor f) => Functor (MaybeT f) where
fmap f (MaybeT m) = MaybeT ((fmap . fmap) f m)
instance (Applicative f) => Applicative (MaybeT f) where
pure a = MaybeT (pure (pure a))
(MaybeT f) <*> (MaybeT m) = MaybeT ( (<*>) <$> f <*> m)
Now you just need a way to convert something in the inner applicative, f, into the combined applicative MaybeT f:
lift :: (Functor f) => f a -> MaybeT f a
lift = MaybeT . fmap Just
This looks like a lot of boilerplate, but ghc can automatically derive nearly all of it.
Now you can easily use the combined functions:
*Main Control.Applicative> runMaybeT $ pure (*2) <*> lift [1,2,3,4]
[Just 2,Just 4,Just 6,Just 8]
*Main Control.Applicative> runMaybeT $ MaybeT (pure Nothing) <*> lift [1,2,3,4]
[Nothing,Nothing,Nothing,Nothing]
This behavior at Nothing may be surprising, but if you think of a list as representing indeterminism you can probably see how it could be useful. If you wanted the dual behavior of returning either Just [a] or Nothing, you just need a transformed List ListT Maybe a.
This isn't quite the same as the instance I wrote for DApplicative. The reason is because of the types. DApplicative converts an f into a g. That's only possible when you know the specific f and g. To generalize it, the result needs to combine the behaviors of both f and g as this implementation does.
All of this works with Monads too. Transformed types such as MaybeT are provided by monad transformer libraries such as mtl.
Your DApplicative instance for Maybe is not complete: What should happen if the first argument of <*:*> is Nothing?
The choice what to do for every combination isn't clear. For two lists <*> would generate all combinations: [(+2),(+10)] <*> [3,4] gives [5,6,13,14]. For two ZipLists you have a zip-like behaviour: (ZipList [(+2),(+10)]) <*> (ZipList [3,4]) gives [5,14]. So you have to choose one of both possible behaviours for a DApplicative of a list and a ZipList, there is no "correct" version.