Fmapping over functors - haskell

Say I have the following code:
data LiftItOut f a = LiftItOut (f a)
deriving Show
instance (Functor fct) => Functor (LiftItOut fct) where
fmap f (LiftItOut fctor) = LiftItOut (fmap f fctor)
If I try calling fmap (\x-> 3 x) (LiftItOut (+3)) it doesn't work. Though, wouldn't it make sense to work? The result would be LiftItOut (fmap (\x ->3 x) (+3)) and, as I see it, the 3 would be fed to (+3) and the result would be wrapped in LiftItOut. I read about (->r) functors on learnyouahaskell though it didn't click with me. Appreciate any and every bit of help

You're right in that you'd get to LiftItOut (fmap (\x -> 3 x) (+3)), and you correctly identified that the wrapped functor of interest is the function functor (N.B. the (r ->) functor, not the (-> r) functor), but your reasoning from there got a bit sloppy. Recall that for functions, we have fmap = (.). So:
LiftItOut (fmap (\x -> 3 x) (+3))
= { fmap = (.) }
LiftItOut ((\x -> 3 x) . (+3))
= { f . g = \y -> f (g y) }
LiftItOut (\y -> (\x -> 3 x) ((+3) y))
= { section application }
LiftItOut (\y -> (\x -> 3 x) (y + 3))
= { lambda application }
LiftItOut (\y -> 3 (y + 3))
...not exactly the result you were thinking you'd get, I wager! And hopefully in this simplified form it's more clear why this isn't really sensible: y + 3 is probably sensible enough, but you are attempting to provide that as an argument to 3, which isn't really a function.

Related

Is (fmap f) the same as (f .) if f is a function of type a->b?

I am trying to implement a Functor instance of
data ComplicatedA a b
= Con1 a b
| Con2 [Maybe (a -> b)]
For Con2, my thought process was the fmap needs to be something like
fmap f (Con2 xs) = Con2 (map f' xs)
then I need to have a list map function f' like
Maybe (a -> x) -> Maybe (a -> y)
Since Maybe is a Functor, I can write f' like
fmap ((a->x) -> (a->y))
In order to get ((a->x) -> (a->y)), I thought I could just do
fmap (x->y) which is the same as (fmap f)
So my sulotion was
instance Functor (ComplicatedA a) where
fmap f (Con1 x y) = Con1 x (f y)
fmap f (Con2 xs) = Con2 (map (fmap (fmap f)) xs)
However the real solution uses (f .) instead of (fmap f) to get ((a->x) -> (a->y)) from x -> y and it looks like this
instance Functor (ComplicatedA a) where
fmap f (Con1 a b) = Con1 a (f b)
fmap f (Con2 l) = Con2 (map (fmap (f .)) l)
I was just wondering what the problem was with my thought process and solution. Is (fmap f) the same as (f .) if f is a function of type a->b?
Thank you in advance.
The solutions are indeed equivalent. fmap for the function/reader functor is (.):
instance Functor ((->) r) where
fmap = (.)
((->) r is the function type constructor being used with prefix syntax -- (->) r a is the same as r -> a.)
The intuition is that, as you have noted, (.) :: (x -> y) -> (a -> x) -> (a -> y) uses a x -> y function to modify the results of an a -> x function.

Point free style with infix notation

Hello is there a way to write point free style when using infix notation?
f::Int->Int->Int->Int
f a b=(+) (a+b)
Why you cannot do something like this ?
f::Int->Int->Int->Int
f a b=(a+b) +
or
f a b= (a+b) `+`
Can you not combine operators in point free style like e.g?
ptfree::Int->Int->Int->Int
ptfree=(+) (+)
I mean you can chop arguments of functions like fold but why not for operator arguments?
Well since you need to pass two parameters, we can use what is known as the "surprised owl operator". This is basically a composition of parameters. So we can use:
f = ((.).(.)) (+) (+)
Or we can more inline the operator like:
f = ((+) .) . (+)
The owl operator ((.).(.)) f g basically is short for \x y -> f (g x y)
How does this work?
The canonical form of the "surprised owl operator" is:
= ((.) . (.))
------------- (canonical form)
(.) (.) (.)
So we can now replace the (.)s with corresponding lambda expressions:
(\f g x -> f (g x)) (.) (.)
So now we can perform some replacements:
(\f g x -> f (g x)) (.) (.)
-> (\x -> (.) ((.) x))
-> (\x -> (\q r y -> q (r y)) ((.) x))
-> (\x -> (\r y -> ((.) x) (r y)))
-> (\x r y -> ((.) x) (r y))
-> (\x r y -> ((\s t u -> s (t u)) x) (r y))
-> (\x r y -> (\t u -> x (t u)) (r y))
-> (\x r y -> (\u -> x ((r y) u)))
-> \x r y u -> x ((r y) u))
-> \x r y u -> x (r y u)
So basically it means that our surprised owl operator, is equal to:
surprised_owl :: (y -> z) -> (a -> b -> y) -> a -> b -> z
surprised_owl f g x y = f (g x y) -- renamed variables
And if we now specialize this with the fuctions provided (two times (+)), we get:
f = surprised_owl (+) (+)
so:
f x y = (+) ((+) x y)
You must compose (+) with (+) twice, for it to be completely point-free: f = ((+) .) . (+)
Recall that composition is defined as
(f . g) x = f (g x)
or, equivalently:
(f . g) = \x -> f (g x)
So, if you look at the composition f = ((+) .) . (+) and work backwards using the definition of (.):
f = ((+) .) . (+)
f = \x -> ((+) .) ((+) x) -- definition of (.)
f = \y -> (\x -> (+) (((+) x) y)) -- definition of (.)
f x y = (+) (((+) x) y) -- a simpler way to write this
f x y z = (+) (((+) x) y) z -- explicitly add in the final argument (eta expansion)
f x y z = ((+) x y) + z -- rewrite as infix
f x y z = (x + y) + z -- rewrite as infix
and you see we end up with what we started before we tried to make it point-free, so we know that this definition works. Going the other way through the steps above, roughly bottom-to-top, could give you an idea of how you might find such a point-free definition of a function like f.
When you "leave off" multiple arguments from the "end" like this, you usually must compose multiple times. Working through a few similar functions should help build intuition for this.
Note: I wouldn't generally recommend using this sort of point-free (when it complicates things) in production code.

How one parameter is used by two function simultaneously

I am reading about applicative functors and found such line:
(+) <$> (+3) <*> (*100) $ 5
It outputs 508.
How 5 could be used by (+3) and (*100) at the same time?
Why don't we need to pass two 5's as a parameters like:
(+) <$> (+3) <*> (*100) $ 5 5
In the (->) a applicative instance, we find:
instance Applicative ((->) a) where
pure = const
(<*>) f g x = f x (g x)
liftA2 q f g x = q (f x) (g x)
So, x is passed to both f and g by definition.
Here is a way to unbox it. We start with
e = ((+) <$> (+3)) <*> (*100)
(note that I left out the $ 5). The Applicative Functor whose <$> and <*> we are using here is the Function type (->) (partially applied to, I guess, Integer). Here, the meaning of <$> and <*> is as follows:
f <$> g = \y -> f (g y)
g <*> h = \x -> g x (h x)
We can plug that in into the term in the first line and get
e = \x -> (\y -> (+) ((+3) y)) x ((*100) x
There are a few simplifications that we can do to this term:
e = \x -> (x+3) + (x*100)
So if this function is the value of (+) <$> (+3) <*> (*100), then it should no longer be surprising that applying this to 5 gives
e 5 = (5+3) + (5*100) = 508
The thing is, you first have to understand how a function can be a functor. Think about a function like a container which reveals it's content only when you feed it with a parameter. In other words we only get to know it's content when this applicative functor (function) gets invoked with a parameter. So the type of this function would be say r -> a on two different types. However for functors we can only take an effect on a single type. So applicative functors are partially applied types just like the functor instance of Either type. We are interested in the output of the function so our applicative functor becomes (->) r in prefix notation. By remembering that <$> is the infix form of fmap
(+3) <$> (*2) $ 4 would result 11. 4 is applied to our functor (*2) and the result (which is the value in the applicative functor context) gets mapped with (+3).
However in our case we are fmaping (+) to (+3). To make it clearer lets rephrase the functions in lambda form.
(+) = \w x -> w + x and (+3) = \y -> y + 3.
then (+) <$> (+3) by partially applying \y -> y + 3 in the place of w our fmap applied applicative functor becomes \y x -> (y + 3) + x.
Now here comes the applicative operator <*>. As mentioned in previous answers it is of definition g <*> h = \x -> g x (h x) which takes a two parameter function g and partially applies g's second parameter with it's second parameter function h. Now our operation looks like
(\y x -> (y + 3) + x) <*> (*100) which can be rephrased as;
(\y x -> (y + 3) + x) <*> (\z -> z*100) which means now we have to partially apply \z -> z*100 to x and our function becomes \y z -> (y + 3) + (z*100).
Finally the applicative operator returns us a function which takes a single parameter and applies it to both parameters of the above two parameter function. So
\x -> (\y z -> (y + 3) + (z*100)) x x

What are the applicative functor laws in terms of pure and liftA2?

I'm playing around with formulating Applicative in terms of pure and liftA2 (so that (<*>) = liftA2 id becomes a derived combinator).
I can think of a bunch of candidate laws, but I'm not sure what the minimal set would be.
f <$> pure x = pure (f x)
f <$> liftA2 g x y = liftA2 ((f .) . g) x y
liftA2 f (pure x) y = f x <$> y
liftA2 f x (pure y) = liftA2 (flip f) (pure y) x
liftA2 f (g <$> x) (h <$> y) = liftA2 (\x y -> f (g x) (h y)) x y
...
Based on McBride and Paterson's laws for Monoidal(section 7) I'd suggest the following laws for liftA2 and pure.
left and right identity
liftA2 (\_ y -> y) (pure x) fy = fy
liftA2 (\x _ -> x) fx (pure y) = fx
associativity
liftA2 id (liftA2 (\x y z -> f x y z) fx fy) fz =
liftA2 (flip id) fx (liftA2 (\y z x -> f x y z) fy fz)
naturality
liftA2 (\x y -> o (f x) (g y)) fx fy = liftA2 o (fmap f fx) (fmap g fy)
It isn't immediately apparent that these are sufficient to cover the relationship between fmap and Applicative's pure and liftA2. Let's see if we can prove from the above laws that
fmap f fx = liftA2 id (pure f) fx
We'll start by working on fmap f fx. All of the following are equivalent.
fmap f fx
liftA2 (\x _ -> x) (fmap f fx) ( pure y ) -- by right identity
liftA2 (\x _ -> x) (fmap f fx) ( id (pure y)) -- id x = x by definition
liftA2 (\x _ -> x) (fmap f fx) (fmap id (pure y)) -- fmap id = id (Functor law)
liftA2 (\x y -> (\x _ -> x) (f x) (id y)) fx (pure y) -- by naturality
liftA2 (\x _ -> f x ) fx (pure y) -- apply constant function
At this point we've written fmap in terms of liftA2, pure and any y; fmap is entirely determined by the above laws. The remainder of the as-yet-unproven proof is left by the irresolute author as an exercise for the determined reader.
If you define (<.>) = liftA2 (.) then the laws become very nice:
pure id <.> f = f
f <.> pure id = f
f <.> (g <.> h) = (f <.> g) <.> h
Apparently pure f <.> pure g = pure (f . g) follows for free. I believe this formulation originates with Daniel Mlot.
Per the online book, Learn You A Haskell:Functors, Applicative Functors and Monoids, the Appplicative Functor laws are bellow but reorganized for formatting reasons; however, I am making this post community editable since it would be useful if someone could embed derivations:
identity] v = pure id <*> v
homomorphism] pure (f x) = pure f <*> pure x
interchange] u <*> pure y = pure ($ y) <*> u
composition] u <*> (v <*> w) = pure (.) <*> u <*> v <*> w
Note:
function composition] (.) = (b->c) -> (a->b) -> (a->c)
application operator] $ = (a->b) -> a -> b
Found a treatment on Reddit

Applicative functors: why can fmap take a function with more than one argument?

I am getting into Haskell and found the book "learn you a Haskell" most helpful. I am up to the section on applicative functors.
I am puzzled by the following as it appears in the book:
(\x y z -> [x, y, z]) <$> (+3) <*> (*2) <*> (/2) $ 5
which yields the output:
[8.0,10.0,2.5]
First of all, I have confirmed my suspicion in ghci in regards to precedence of the operators, so that the above equals the following ugly statement:
(((\x y z -> [x,y,z]) <$> (+3)) <*> (*2) <*> (/2)) $ 5
So from that it becomes clear that the first thing that happens is the fmap call via the (<$>) infix operator.
And this is the core of what boggles my mind currently.
The definition of fmap (here shown as infix (<$>)) is:
(<$>) :: (Functor f) => (a -> b) -> f a -> f b
But in the equation I am struggling with, (\x y z -> [x, y, z]) takes three arguments, not just one. So how could the first argument of type (a -> b) be satisfied?
I think it might have to do with partial application / currying but I cannot figure it out. I would greatly appreciate an explanation. Hope I have formulated the question well enough.
Simple answer: there are no functions with multiple arguments in Haskell!
There are two candidates for what you might call "dyadic function": a function that takes a (single!) tuple, and – by far prevalent in Haskell – curried functions. Those take just one argument, but the result is a function again.
So, to figure out what e.g. fmap (+) does, let's write
type IntF = Int -> Int
-- (+) :: Int -> IntF
-- fmap :: ( a -> b ) -> f a -> f b
-- e.g.:: (Int->IntF) -> f Int->f IntF
Test it yourself in GHCi:
Prelude> type IntF = Int -> Int
Prelude> let (#) = (+) :: Int -> IntF
Prelude> :t fmap (#)
fmap (#) :: Functor f => f Int -> f IntF
Consider a function of type
f :: a -> b -> c -> d
where d is any other type. Due to currying, this can be thought of as a function with the following type
f :: a -> (b -> c -> d)
i.e. a function that takes an a and returns function of type b -> c -> d. If you apply fmap, you have
-- the type of fmap, which is also :: (a -> r) -> (f a -> f r)
fmap :: Functor f => (a -> r) -> f a -> f r
-- the type of f
f :: a -> (b -> c -> d)
-- so, setting r = b -> c -> d
fmap f :: f a -> f (b -> c -> d)
Which is now of the right type to be used as the left-hand argument to (<*>).
Because you can take a 3-argument function, feed it just one argument, and this results in a 2-argument function. So you're going to end up with a list of 2-argument functions. You can then apply one more argument, ending up with a list of 1-argument functions, and finally apply the last argument, whereupon you end up with a list of ordinary numbers.
Incidentally, this is why Haskell has curried functions. It makes it easy to write constructs like this one which work for any number of function arguments. :-)
I personally find the applicative functor instance for functions a bit strange. I'll walk you through this example to try to understand intuitively what's going on:
>>> :t (\x y z -> [x, y, z]) <$> (+3)
... :: Num a => a -> a -> a -> [a]
>>> ((\x y z -> [x, y, z]) <$> (+3)) 1 2 3
[4,2,3]
This applies (+3) to the first parameter of the inner function. The other 2 outer parameters are passed to the inner function unmodified.
Let's add an applicative:
>>> :t (\x y z -> [x, y, z]) <$> (+3) <*> (*2)
... :: Num a => a -> a -> [a]
>>> ((\x y z -> [x, y, z]) <$> (+3) <*> (*2)) 1 2
[4,2,2]
This applies (+3) to the first argument as before. With the applicative, the first outer parameter (1) is applied (*2) and passed as the second parameter of the inner function. The second outer parameter is passed unmodified to the inner function as its third parameter.
Guess what happens when we use another applicative:
>>> :t (\x y z -> [x, y, z]) <$> (+3) <*> (*2) <*> (/2)
... :: Fractional a => a -> [a]
>>> (\x y z -> [x, y, z]) <$> (+3) <*> (*2) <*> (/2) $ 1
[4.0,2.0,0.5]
3 applications to the same parameter passed as 3 arguments to the inner function.
It's not theoretically solid explanation, but it can give an intuition about how the applicative instance of functions works.
Background
Let's start with the definition of the <*> and pure for functions as an instance of Applicative. For pure, it will take any garbage value, and return x. For <*>, you can think of it as applying x to f, getting a new function out of it, then applying it to the output of g x.
instance Applicative ((->) r) where
pure x = (\_ -> x)
f <*> g = \x -> f x (g x)
Now, let's look at the definition of <$>. It is just an infix version of fmap.
(<$>) :: (Functor f) => (a -> b) -> f a -> f b
f <$> x = fmap f x
Recall that fmap has the following implementation:
instance Functor ((->) r) where
fmap f g = (\x -> f (g x))
Proving that f <$> x is just pure f <*> x
Let's start with pure f <*> x. Replace pure f with (\_ -> f).
pure f <*> x
= (\_ -> f) <*> x
Now, let's apply the definition of <*>, which is f <*> g = \q -> f q (g q).
(\_ -> f) <*> x
= \q -> (\_ -> f) q (x q)
Notice we can simplify (\_ -> f) q as just f. The function takes in whatever value we give it, and returns f.
\q -> (\_ -> f) q (x q)
= \q -> f (x q)
That looks just like our definition of fmap! And the <$> operator is just infix fmap.
\q -> f (x q)
= fmap f x
= f <$> x
Let's keep this in mind: f <$> g is just pure f <*> g.
Understanding (\x y z -> [x, y, z]) <$> (+3) <*> (*2) <*> (/2) $ 5
First step is to rewrite the left side of expression to use <*> instead of <$>. Using what we just proved in in the previous section:
(\x y z -> [x, y, z]) <$> (+3)
= pure (\x y z -> [x, y, z]) <*> (+3)
So the full expression becomes
pure (\x y z -> [x, y, z]) <*> (+3) <*> (*2) <*> (/2) $ 5
Let's simplify the first operator using the definition of <*>
pure (\x y z -> [x, y, z]) <*> (+3)
= \a -> f a (g a) --substitute f and g
= \a -> pure (\x y z -> [x, y, z]) a ((+3) a)
Now let's substitute pure x with (\_ -> x). Observe that a becomes the garbage value that's used as _, and is consumed to return the function (\x y z -> [x, y, z]).
\a -> (\_-> (\x y z -> [x, y, z])) a ((+3) a)
= \a -> (\x y z -> [x, y, z]) ((+3) a)
Now let's look back at the full expression, and tackle the next <*>. Again, let's apply the definition of <*>.
(\a -> (\x y z -> [x, y, z]) ((+3) a)) <*> (*2)
= \b -> (\a -> (\x y z -> [x, y, z]) ((+3) a)) b ((*2) b)
Finally, let's repeat this one last time for the final <*>.
(\b -> (\a -> (\x y z -> [x, y, z]) ((+3) a)) b ((*2) b)) <*> (/2)
= \c -> (\b -> (\a -> (\x y z -> [x, y, z]) ((+3) a)) b ((*2) b)) c ((/2) c)
Notice that it's a function that takes a single value. We'll feed it 5.
(\c -> (\b -> (\a -> (\x y z -> [x, y, z]) ((+3) a)) b ((*2) b)) c ((/2) c)) 5
(\5 -> (\b -> (\a -> (\x y z -> [x, y, z]) ((+3) a)) b ((*2) b)) 5 ((/2) 5))
(\b -> (\a -> (\x y z -> [x, y, z]) ((+3) a)) b ((*2) b)) 5 (2.5 )
(\5 -> (\a -> (\x y z -> [x, y, z]) ((+3) a)) 5 ((*2) 5)) (2.5 )
(\a -> (\x y z -> [x, y, z]) ((+3) a)) 5 (10 ) (2.5 )
(\5 -> (\x y z -> [x, y, z]) ((+3) 5)) (10 ) (2.5 )
(\x y z -> [x, y, z]) (8 ) (10 ) (2.5 )
(\x y z -> [x, y, z]) (8) (10) (2.5)
= [8, 10, 2.5]
And that's how we get the final answer.

Resources