I have following instance of Traversable:
instance Traversable (Three' a) where
traverse f (Three' x y z) = Three' x <$> f y <*> f z
the infix operator <$> and <*> has the same precedence and namely 4.
*ExercisesTraversable> :i <$>
(<$>) :: Functor f => (a -> b) -> f a -> f b
-- Defined in ‘Data.Functor’
infixl 4 <$>
*ExercisesTraversable> :i <*>
class Functor f => Applicative (f :: * -> *) where
...
(<*>) :: f (a -> b) -> f a -> f b
...
-- Defined in ‘GHC.Base’
infixl 4 <*>
Which one is going to executed first?
They don't just have precedence 4, they also have left-associativity. This is the l in infixl; one can also choose infixr for right-associativity, and infix for "throw an error if you need to know what the associativity should be". Thus
Three' x <$> f y <*> f z
is parsed as:
(Three' x <$> f y) <*> f z
As for which is executed first, that can't be answered without seeing the implementation of (<*>) that you want to ask about; Three' x <$> f y will be evaluated just far enough for (<*>) to make progress, as usual, so if (<*>) can make progress without evaluating the (<$>) call first, it will.
Related
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))
Applicative is declared as
class Functor f => Applicative f where
pure :: a -> f a
(<*>) :: f (a -> b) -> f a -> f b
One of applicative's laws is:
x <*> y <*> z = ( pure (.) <*> x <*> y) <*> z
where (.) is composition between functions:
(.) :: (b -> c) -> (a -> b) -> (a -> c)
f . g = \x -> f (g x)
On the right hand side of the law,
does pure (.) have type f((b -> c) -> (a -> b) -> (a -> c))?
does x have type f(b->c)?
does y have type f(a->b)?
does z have type f(a)?
On the left hand side of the law,
does x have type f(a->b->c)?
does y have type f(a)?
does z have type f(b)?
Thanks.
The applicative laws are easier understood in the equivalent monoidal functor representation:
class Functor f => Monoidal f where
pureUnit :: f ()
fzip :: f a -> f b -> f (a,b)
--pure x = fmap (const x) pureUnit
--fs<*>xs = fmap (\(f,x)->f x) $ fzip fs xs
--pureUnit = pure ()
--fzip l r = (,) <$> l <*> r
Then, the law you're asking about is this:
fzip x (fzip y z) ≅ fzip (fzip x y) z
where by p ≅ q I mean, equivalent up to re-association of the tuple type, i.e. explicitly
fzip x (fzip y z) ≡ fmap (\((a,b),c)->(a,(b,c))) $ fzip (fzip x y) z
So this is really just an associative law. Even better visible when written with an infix (⋎) = fzip:
x ⋎ (y ⋎ z) ≅ (x ⋎ y) ⋎ z
Stating the law again for ease of reference (which I have corrected by putting the parenthese in, `(<*>) is left associative so the ones on the LHS of the equality are necessary):
x <*> (y <*> z) = ( pure (.) <*> x <*> y) <*> z
let's start with your first question:
On the right hand side of the law,
does pure (.) have type f((b -> c) -> (a -> b) -> (a -> c))?
Yes it does. (.) has type (b -> c) -> (a -> b) -> (a -> c), so pure (.) must have type "f of that".
We can use this to determine the types of the other identifiers here. In the expression m <*> n, m and n have the general types f (a -> b) and f a. So if we take m as (.), which has the type shown above, we see that n - which corresponds to x on the RHS of the equality - must have type f (b -> c). And then pure (.) <*> x will have type f ((a -> b) -> (a -> c)), which by the same reasoning means y will have type f (a -> b). This produces a type of f (a -> c) for ( pure (.) <*> x <*> y) and of f a for z - and thus an overall result type, for the whole RHS (and therefore also the whole LHS) of f c.
So to summarise, just from analysing the RHS, we see that:
x :: f (b -> c)
y :: f (a -> b)
z :: f a
It's now easy to check that these work out on the LHS too - y <*> z will have type f b, so x <*> (y <*> z) will have type f c.
I note that there's nothing clever involved in the above, it's just simple type algebra, which can be carried out without any advanced understanding.
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>
I am having some trouble understanding how the function instance (->) r of Applicative works in Haskell.
For example if I have
(+) <$> (+3) <*> (*100) $ 5
I know you get the result 508, I sort of understand that you take the result of (5 + 3) and (5 * 100) and you apply the (+) function to both of these.
However I do not quite understand what is going on. I assume that the expression is parenthesized as follows:
((+) <$> (+3)) <*> (*100)
From my understanding what is happening is that your mapping (+) over the eventual result of (+3) and then you are using the <*> operator to apply that function to the eventual result of (*100)
However I do not understand the implementation of <*> for the (->) r instance and why I cannot write:
(+3) <*> (*100)
How does the <*>, <$> operator work when it comes to (->) r?
<$> is just another name for fmap and its definition for (->) r is (.) (the composition operator):
intance Functor ((->) r) where
fmap f g = f . g
You can basically work out the implementation for <*> just by looking at the types:
instance Applicative ((->) r) where
(<*>) :: (r -> a -> b) -> (r -> a) -> (r -> b)
f <*> g = \x -> f x (g x)
You have a function from r to a to b and a function from r to a. You want a funtion from r to b as a result. First thing you know is you return a function:
\x ->
Now you want to apply f since it is the only item which may return a b:
\x -> f _ _
Now the arguments for f are of type r and a. r is simply x (since it alrady is of type r and you can get an a by applying g to x:
\x -> f x (g x)
Aaand you're done. Here's a link to the implementation in Haskell's Prelude.
Consider the type signature of <*>:
(<*>) :: Applicative f => f (a -> b) -> f a -> f b
Compare this to the type signature for ordinary function application, $:
($) :: (a -> b) -> a -> b
Notice that they are extremely similar! Indeed, the <*> operator effectively generalizes application so that it can be overloaded based on the types involved. This is easy to see when using the simplest Applicative, Identity:
ghci> Identity (+) <*> Identity 1 <*> Identity 2
Identity 3
This can also be seen with slightly more complicated applicative functors, such as Maybe:
ghci> Just (+) <*> Just 1 <*> Just 2
Just 3
ghci> Just (+) <*> Nothing <*> Just 2
Nothing
For (->) r, the Applicative instance performs a sort of function composition, which produces a new function that accepts a sort of “context” and threads it to all of the values to produce the function and its arguments:
ghci> ((\_ -> (+)) <*> (+ 3) <*> (* 100)) 5
508
In the above example, I have only used <*>, so I’ve explicitly written out the first argument as ignoring its argument and always producing (+). However, Applicative typeclass also includes the pure function, which has the same purpose of “lifting” a pure value into an applicative functor:
ghci> (pure (+) <*> (+ 3) <*> (* 100)) 5
508
In practice, though, you will rarely see pure x <*> y because it is precisely equivalent to x <$> y by the Applicative laws, since <$> is just an infix synonym for fmap. Therefore, we have the common idiom:
ghci> ((+) <$> (+ 3) <*> (* 100)) 5
508
More generally, if you see any expression that looks like this:
f <$> a <*> b
…you can read it more or less like the ordinary function application f a b, except in the context of a particular Applicative instance’s idioms. In fact, an original formulation of Applicative proposed the idea of “idiom brackets”, which would add the following as syntactic sugar for the above expression:
(| f a b |)
However, Haskellers seem to be satisfied enough with the infix operators that the benefits of adding the additional syntax has not been deemed worth the cost, so <$> and <*> remain necessary.
Let's take a look at the types of these functions (and the definitions that we automatically get along with them):
(<$>) :: (a -> b) -> (r -> a) -> r -> b
f <$> g = \x -> f (g x)
(<*>) :: (r -> a -> b) -> (r -> a) -> r -> b
f <*> g = \x -> f x (g x)
In the first case, <$>, is really just function composition. A simpler definition would be (<$>) = (.).
The second case is a little more confusing. Our first input is a function f :: r -> a -> b, and we need to get an output of type b. We can provide x :: r as the first argument to f, but the only way we can get something of type a for the second argument is by applying g :: r -> a to x :: r.
As an interesting aside, <*> is really the S function from SKI combinatory calculus, whereas pure for (-> r) is the K :: a -> b -> a (constant) function.
As a Haskell newbie myself, i'll try to explain the best way i can
The <$> operator is the same as mapping a function on to another function.
When you do this:
(+) <$> (+3)
You are basically doing this:
fmap (+) (+3)
The above will call the Functor implementation of (->) r which is the following:
fmap f g = (\x -> f (g x))
So the result of fmap (+) (+3) is (\x -> (+) (x + 3))
Note that the result of this expression has a type of a -> (a -> a)
Which is an applicative! That is why you can pass the result of (+) <$> (+3) to the <*> operator!
Why is it an applicative you might ask? Lets look the at the <*> definition:
f (a -> b) -> f a -> f b
Notice that the first argument matches our returned function definition a -> (a -> a)
Now if we look at the <*> operator implementation, it looks like this:
f <*> g = (\x -> f x (g x))
So when we put all those pieces together, we get this:
(+) <$> (+3) <*> (+5)
(\x -> (+) (x + 3)) <*> (+5)
(\y -> (\x -> (+) (x + 3)) y (y + 5))
(\y -> (+) (y + 3) (y + 5))
The (->) e Functor and Applicative instances tend to be a bit confusing. It may help to view (->) e as an "undressed" version of Reader e.
newtype Reader e a = Reader
{ runReader :: e -> a }
The name e is supposed to suggest the word "environment". The type Reader e a should be read as "a computation that produces a value of type a given an environment of type e".
Given a computation of type Reader e a, you can modify its output:
instance Functor (Reader e) where
fmap f r = Reader $ \e -> f (runReader r e)
That is, first run the computation in the given environment, then apply the mapping function.
instance Applicative (Reader e) where
-- Produce a value without using the environment
pure a = Reader $ \ _e -> a
-- Produce a function and a value using the same environment;
-- apply the function to the value
rf <*> rx = Reader $ \e -> (runReader rf e) (runReader rx e)
You can use the usual Applicative reasoning for this as any other applicative functor.
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.