(fmap.fmap) for Applicative - haskell

fmap.fmap allows us to go "two layers deep" into a functor:
fmap.fmap :: (a -> b) -> f (g a) -> f (g b)
Is this also possible for applicative functors? Let's say I wanted to combine Just (+5) and [1,2,3] by using their applicative properties. I can think of an obvious way to do it, but it doesn't seem that trivial to me.
(<*>).(<*>) doesn't a have a conclusive type signature:
((<*>).(<*>)) :: (a1 -> a2 -> b) -> ((a1 -> a2) -> a1) -> (a1 -> a2) -> b
-- where I would expect something like:
-- ((<*>).(<*>)) :: f (g (a -> b)) -> f (g a) -> f (g b)
Is it possible to compose Just (+5) and [1,2,3] in this fashion?
EDIT:
The first step would be to go with either:
pure $ Just (+5) and fmap pure [1,2,3], or
fmap pure (Just (+5) and pure [1,2,3]
But I still don't how to compose these...
EDIT:
It would be nice to have a general way to compose a function f (g (a -> b) and f (g a), I'm not just looking for a solution for the above case, which is just supposed to serve as an example input of such a function. Basically I want a function:
(<***>) :: f (g (a -> b)) -> f (g a) -> f (g b)

liftA2 has a similar compositional property as fmap.
liftA2 f :: f a -> f b -> f c
(liftA2 . liftA2) f :: g (f a) -> g (f b) -> g (f c)
So you can write
(liftA2 . liftA2) ($) (pure (Just (+5))) (fmap pure [1,2,3]) :: [Maybe Integer]
i.e., (<***>) = (liftA2 . liftA2) ($). (much like (<*>) = liftA2 ($))
Another way to look at it is that the composition of applicative functors is an applicative functors, this is made concrete by Data.Functor.Compose:
{-# LANGUAGE ScopedTypeVariables, PartialTypeSignatures #-}
import Data.Functor.Compose
import Data.Coerce
(<***>) :: forall f g a b. (Applicative f, Applicative g)
=> f (g (a -> b)) -> f (g a) -> f (g b)
(<***>) = coerce ((<*>) :: Compose f g (a -> b) -> _)
The point with coerce is to show that (<***>) is the applicative (<*>) for the right type; we can also do the unwrapping manually
f <***> x = getCompose $ Compose f <*> Compose x

We have a f (g (a->b)). To get g a -> g b from g (a->b) we just need <*>, but g (a->b) is wrapped in f. Luckily f is a Functor so we can fmap over it.
Prelude> :t fmap (<*>)
fmap (<*>)
:: (Functor f1, Applicative f) =>
f1 (f (a -> b)) -> f1 (f a -> f b)
Prelude>
That's better, we have a function wrapped in a Functor now. If this Functor happens to be an Applicative, we can apply <*> through it.
Prelude> :t (<*>) . fmap (<*>)
(<*>) . fmap (<*>)
:: (Applicative f, Applicative f1) =>
f1 (f (a -> b)) -> f1 (f a) -> f1 (f b)
Prelude>
Just what the doctor ordered.
Prelude> let (<***>) = (<*>) . fmap (<*>)
Prelude> [Just (+2), Just (*3), Nothing] <***> [Just 7, Just 42, Nothing]
[Just 9,Just 44,Nothing,Just 21,Just 126,Nothing,Nothing,Nothing,Nothing]
Prelude>

Related

How to understand the type of (fmap fmap fmap) in Haskell?

In Haskell, the Functor has a function fmap which the type of it is:
ghci> :t fmap
fmap :: Functor f => (a -> b) -> f a -> f b
This makes sense to me that fmap lifts a function from the type of a -> b to f a -> f b.
Then I am curious about what is the type of fmap fmap, so I tried and got something weird to me:
ghci> :t fmap fmap
fmap fmap
:: (Functor f1, Functor f2) => f1 (a -> b) -> f1 (f2 a -> f2 b)
Hmm, this type is somewhat complicate, but I can explain it by replacing a with a -> b and b with f2 a -> f2 b.
Then, I wanted to one step further:
fmap fmap fmap
:: (Functor f1, Functor f2) => (a -> b) -> f1 (f2 a) -> f1 (f2 b)
Oh, wait! Things go to be fun when putting 3 fmap together. How to explain this?
Could someone help to explain how could I derive the type of fmap fmap fmap?
For clarity, let's introduce
fmapA, fmapB, fmapC :: Functor f => (a -> b) -> f a -> f b
fmapA = fmapB = fmapC = fmap
and consider
fmapA fmapB fmapC :: ?
Forget about fmapB for a bit, start with fmapA _ fmapC. You're treating fmapC on the right as a container here, over which you map something. Does that make sense? Well, look at the type in non-infix form. Recall that x -> y -> z is the same as x -> (y -> z), and p -> q is the same as ((->) p) q, thus
fmapC :: ((->) p) q where {p ~ (a->b), q ~ (f a->f b)}
To use this as a container type, the f in fmapA's signature needs to unify with (->) p. That's the function functor. So, despite having three polymorphic fmaps here, one of the functors is already predetermined by the expression. Therefore, it would be better to immediately resolve the polymorphism that only makes it more difficult to understand, and replace it with the definition of that particular functor instance, which turns out to be rather simple:
instance Functor ((->) a) where
fmap = (.)
So, that reduces our expression to (.) fmapB fmapC – or, as it's preferrably written,
fmapB . fmapC
Which is a far more sensible thing to write in actual code, and has been discussed previously on StackOverflow.
{-# Language BlockArguments #-}
{-# Language ScopedTypeVariables #-}
{-# Language TypeApplications #-}
fffmap
:: forall f g a b. ()
=> Functor f
=> Functor g
=> (a -> b)
-> (f (g a) -> f (g b))
fffmap = fmap fmap fmap
A polymorphic function takes a type as an argument. The forall. quantifiee is invisible and implicitly solved by unification but we can explicitly instantiate it with a type application #...
I use block arguments which allows me to write fmap fmap fmap as
do fmap
do fmap
do fmap
just to make it clearer. This is how they are actually instantiated:
fffmap
:: forall f g a b. ()
=> Functor f
=> Functor g
=> (a -> b)
-> (f (g a) -> f (g b))
fffmap =
do fmap #((->) (a -> b)) #(g a -> g b) #(f (g a) -> f (g b))
do fmap #f #(g a) #(g b)
do fmap #g #a #b
The first fmap = (.) is instantiated to the reader monad (.. ->), no wonder you find it complicated. If you look at the type of f1, it IS complicated.
fffmap
:: forall f g a b.
Functor f
=> Functor g
=> (a -> b)
-> (f (g a) -> f (g b))
fffmap = f1 f2 f3 where
f1 :: ((g a -> g b) -> f (g a) -> f (g b)) -> ((a -> b) -> g a -> g b) -> (a -> b) -> f (g a) -> f (g b)
f1 = fmap
f2 :: (g a -> g b) -> (f (g a) -> f (g b))
f2 = fmap
f3 :: (a -> b) -> (g a -> g b)
f3 = fmap

Composing Applicatives

I'm reading through Chapter 25 (Composing Types) of the haskellbook, and wish to understand applicative composition more completely
The author provides a type to embody type composition:
newtype Compose f g a =
Compose { getCompose :: f (g a) }
deriving (Eq, Show)
and supplies the functor instance for this type:
instance (Functor f, Functor g) =>
Functor (Compose f g) where
fmap f (Compose fga) =
Compose $ (fmap . fmap) f fga
But the Applicative instance is left as an exercise to the reader:
instance (Applicative f, Applicative g) =>
Applicative (Compose f g) where
-- pure :: a -> Compose f g a
pure = Compose . pure . pure
-- (<*>) :: Compose f g (a -> b)
-- -> Compose f g a
-- -> Compose f g b
Compose fgf <*> Compose fgx = undefined
I can cheat and look the answer up online... The source for Data.Functor.Compose provides the applicative instance definition:
Compose f <*> Compose x = Compose ((<*>) <$> f <*> x)
but I'm having trouble understanding what's going on here. According to type signatures, both f and x are wrapped up in two layers of applicative structure. The road block I seem to be hitting though is understanding what's going on with this bit: (<*>) <$> f. I will probably have follow up questions, but they probably depend on how that expression is evaluated. Is it saying "fmap <*> over f" or "apply <$> to f"?
Please help to arrive at an intuitive understanding of what's happening here.
Thanks! :)
Consider the expression a <$> b <*> c. It means take the function a, and map it over the functor b, which will yield a new functor, and then map that new functor over the functor c.
First, imagine that a is (\x y -> x + y), b is Just 3, and c is Just 5. a <$> b then evaluates to Just (\y -> 3 + y), and a <$> b <*> c then evaluates to Just 8.
(If what's before here doesn't make sense, then you should try to understand single layers of applicatives further before you try to understand multiple layers of them.)
Similarly, in your case, a is (<*>), b is f, and c is x. If you were to choose suitable values for f and x, you'd see that they can be easily evaluated as well (though be sure to keep your layers distinct; the (<*>) in your case belongs to the inner Applicative, whereas the <$> and <*> belong to the outer one).
Rather than <*>, you can define liftA2.
import Control.Applicative (Applicative (..))
newtype Compose f g a = Compose
{ getCompose :: f (g a) }
deriving Functor
instance (Applicative f, Applicative g) => Applicative (Compose f g) where
pure a = Compose (pure (pure a))
-- liftA2 :: (a -> b -> c) -> Compose f g a -> Compose f g b -> Compose f g c
liftA2 f (Compose fga) (Compose fgb) = Compose _1
We have fga :: f (g a) and fgb :: f (g b) and we need _1 :: f (g c). Since f is applicative, we can combine those two values using liftA2:
liftA2 f (Compose fga) (Compose fgb) = Compose (liftA2 _2 fga fgb)
Now we need
_2 :: g a -> g b -> g c
Since g is also applicative, we can use its liftA2 as well:
liftA2 f (Compose fga) (Compose fgb) = Compose (liftA2 (liftA2 f) fga fgb)
This pattern of lifting liftA2 applications is useful for other things too. Generally speaking,
liftA2 . liftA2 :: (Applicative f, Applicative g) => (a -> b -> c) -> f (g a) -> f (g b) -> f (g c)
liftA2 . liftA2 . liftA2
:: (Applicative f, Applicative g, Applicative h)
=> (a -> b -> c) -> f (g (h a)) -> f (g (h b)) -> f (g (h c))

Why do the types in `(fmap . fmap) sum Just [1, 2, 3]` work?

I'm having the time of my life reading the wonderful Haskell Programming from first principles and I came by the following example that I'm just not able to take apart (Page 1286 e-reader):
Prelude> (fmap . fmap) sum Just [1, 2, 3]
Just 6
It is obvious to me how the following works:
Prelude> fmap sum $ Just [1,2,3]
Just 6
And I already manually deconstructed (fmap . fmap) to understand how the types work. But when thinking about this as "lifting twice" it doesn't make sense, since I'm lifting over both the Just and List data constructors.
I typed out the following in ghci:
Prelude> :t (fmap . fmap)
(fmap . fmap)
:: (Functor f, Functor f1) => (a -> b) -> f1 (f a) -> f1 (f b)
Prelude> :t (fmap . fmap) sum
(fmap . fmap) sum
:: (Num b, Foldable t, Functor f, Functor f1) =>
f1 (f (t b)) -> f1 (f b)
Prelude> :t (fmap . fmap) sum Just
(fmap . fmap) sum Just :: (Num b, Foldable t) => t b -> Maybe b
I don't understand how to derive the last output. When feeding (fmap . fmap) sum the Just data constructor, How does the compiler know to replace both f1 and f for Maybe? After I'll get a good answer here, how could I have figured it out myself?
That isn't lifting over both Maybe and List (that would be (fmap . fmap) sum (Just [1,2,3]), which has a type problem), but over the function type (->) and Maybe.
Just :: a -> Maybe a
-- ((->) a) (Maybe a)
-- f (g a) for f ~ ((->) a) and g ~ Maybe
(fmap . fmap) :: (a -> b) -> f (g a ) -> f (g b)
-- Num x => ([x] -> x) -> f (g [x]) -> f (g x)
-- Num x => ([x] -> x) -> ([x] -> Maybe [x]) -> [x] -> Maybe x
-- ^ ^ ^
-- sum Just [1,2,3]
If you don't understand how a particular answer works, line up the argument you are supplying with the type from the previous step.
Prelude> :t (fmap . fmap) sum
(fmap . fmap) sum
:: (Functor f, Functor f1, Num b) => f (f1 [b]) -> f (f1 b)
So in order for this work, Just has to have type f (f1 [b]), and then (fmap . fmap) sum Just has to have type f (f1 b).
Just :: (Functor f, Functor f1, Num b) => f (f1 [b])
It's not obvious what f or f1 should be here, so let's try the RHS instead. We can cheat and ask GHCi to check what the actual value of (fmap . fmap) sum Just should be:
Prelude> :t (fmap . fmap) sum Just
(fmap . fmap) sum Just :: Num b => [b] -> Maybe b
But this should match:
(Functor f, Functor f1, Num b) => f (f1 b)
We're trying to figure out what f and f1 are here. So we have to rewrite it a little bit so it has the same structure (remember that -> is syntactic sugar and gets in the way sometimes):
(fmap . fmap) sum Just :: Num b => [b] -> Maybe b
-- Same as...
(fmap . fmap) sum Just :: Num b => (->) [b] (Maybe b)
-- Or...
(fmap . fmap) sum Just :: Num b => ((->) [b]) (Maybe b)
-- Functor f = ((->) [b])
-- Functor f1 = Maybe
So we can figure out that in order for the types to match, the Functor f has to be (->) [b]… remember that functions are functors too! And the Functor f1 is Maybe, which is a bit more obvious.
We can test this out:
Prelude> :t (fmap . fmap) sum :: Num b => ([b] -> Maybe [b]) -> ([b] -> Maybe b)
(fmap . fmap) sum :: Num b => ([b] -> Maybe [b]) -> ([b] -> Maybe b)
:: Num b => ([b] -> Maybe [b]) -> [b] -> Maybe b
And GHCi thinks it type checks just fine.
The only part here that's easy to forget is just that (->) [b] is a valid functor!

How to add applicative effects to a monoid?

How can I change following code so that each element in Maybe monoid element takes also two arguments (so it would become "double" reader applicative)?
g :: (Monoid a, IsString a) => [Maybe a] -> Maybe a
g = foldr (<>) (Just "")
So that result would be of type:
g2 :: (Monoid a, IsString a) => [b -> c -> Maybe a] -> b -> c -> Maybe a
I guess I could lift <> twice:
> :t (liftA2 $ liftA2 (<>))
(liftA2 $ liftA2 (<>))
:: (Monoid c, Applicative f1, Applicative f) =>
f (f1 c) -> f (f1 c) -> f (f1 c)
But I'm stuck trying to compose it with foldr to get the type signature I want.
This is how I would do it
g2 x y = g $ ($ y) <$> ($ x) <$> theList

Parse error in pattern: f . g in fmap (f . g) = fmap f . fmap g

Parse error in pattern: f . g
i am a beginner, where is wrong?
(f . g) x = f (g x)
class Functor f where
fmap :: (a -> b) -> f a -> f b
class Functor g where
fmap :: (a -> b) -> f a -> f b
instance Functor F where
fmap id = id
fmap (f . g) = fmap f . fmap g
When you make an instance of Functor, you should prove the side condition that
fmap id = id
and
fmap (f . g) = fmap f . fmap g
(Technically the latter comes for free given the types involved and the former law, but it is still a good exercise.)
You can't do this just by saying
fmap id = id
but instead you use this as a reasoning tool -- once you have proven it.
That said, the code that you have written doesn't make sense for a number of reasons.
(f . g) x = f (g x)
Since this is indented, I'm somewhat unclear if this is intended to be a definition for (.), but that is already included in the Prelude, so you need not define it again.
class Functor f where
fmap :: (a -> b) -> f a -> f b
This definition is also provided for you in the Prelude.
class Functor g where
fmap :: (a -> b) -> f a -> f b
But then you define the class again, but here it has mangled the signature of fmap, which would have to be
fmap :: (a -> b) -> g a -> g b
But as you have another definition of Functor right above (and the Prelude has still another, you couldn't get that to compile)
Finally, your
instance Functor F where
fmap id = id
fmap (f . g) = fmap f . fmap g
makes up a name F for a type that you want to make into an instance of Functor, and then tries to give the laws as an implementation, which isn't how it works.
Let us take an example of how it should work.
Consider a very simple functor:
data Pair a = Pair a a
instance Functor Pair where
fmap f (Pair a b) = Pair (f a) (f b)
now, to prove fmap id = id, let us consider what fmap id and id do pointwise:
fmap id (Pair a b) = -- by definition
Pair (id a) (id b) = -- by beta reduction
Pair a (id b) = -- by beta reduction
Pair a b
id (Pair a b) = -- by definition
Pair a b
So, fmap id = id in this particular case.
Then you can check (though technically given the above, you don't have to) that fmap f . fmap g = fmap (f . g)
(fmap f . fmap g) (Pair a b) = -- definition of (.)
fmap f (fmap g (Pair a b)) = -- definition of fmap
fmap f (Pair (g a) (g b)) = -- definition of fmap
Pair (f (g a)) (f (g b))
fmap (f . g) (Pair a b) = -- definition of fmap
Pair ((f . g) a) ((f . g) b) = -- definition of (.)
Pair (f (g a)) ((f . g) b) = -- definition of (.)
Pair (f (g a)) (f (g b))
so fmap f . fmap g = fmap (f . g)
Now, you can make function composition into a functor.
class Functor f where
fmap :: (a -> b) -> f a -> f b
by partially applying the function arrow constructor.
Note that a -> b and (->) a b mean the same thing, so when we say
instance Functor ((->) e) where
the signature of fmap specializes to
fmap {- for (->) e -} :: (a -> b) -> (->) e a -> (->) e b
which once you have flipped the arrows around looks like
fmap {- for (->) e -} :: (a -> b) -> (e -> a) -> e -> b
but this is just the signature for function composition!
So
instance Functor ((->)e) where
fmap f g x = f (g x)
is a perfectly reasonable definition, or even
instance Functor ((->)e) where
fmap = (.)
and it actually shows up in Control.Monad.Instances.
So all you need to use it is
import Control.Monad.Instances
and you don't need to write any code to support this at all and you can use fmap as function composition as a special case, so for instance
fmap (+1) (*2) 3 =
((+1) . (*2)) 3 =
((+1) ((*2) 3)) =
((+1) (3 * 2)) =
3 * 2 + 1 =
7
Since . is not a data constructor you cannot use it for pattern matching I believe. As far as I can tell there isn't an easy way to do what you're trying, although I'm pretty new to Haskell as well.
let is not used for top-level bindings, just do:
f . g = \x -> f (g x)
But the complaint, as cobbal said, is about fmap (f . g), which isn't valid. Actually, that whole class Functor F where is screwy. The class is already declared, now I think you want to make and instance:
instance Functor F where
fmap SomeConstructorForF = ...
fmap OtherConstructorForF = ...
etc.

Resources