fmap composition

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

fmap composition

Marco Turchetto
I'm reading the "Haskell programming" book and in chapter 16 about functors they combine two "fmap" with the "(.)" function.
I really don't understand how the type of "fmap . fmap" is "(Functor f2, Functor f1) => (a -> b) -> f1 (f2 a) -> f1 (f2 b)".

The thing that really freaks me out is that I thought that "(.)" arguments are ONLY two unary function.
Maybe there is some curring magic underline, there is someone that can explain to me how the type of "fmap . fmap" is derived from the type of "fmap" and "(.)"?


_______________________________________________
Beginners mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
Reply | Threaded
Open this post in threaded view
|

Re: fmap composition

Ut Primum
Hi,
as you probably know, fmap ha type 
fmap :: Functor f => (a -> b) -> f a -> f b
So, you can see fmap as a unary funcrion that takes an argument of type (a->b) and returns a result of type (f a -> f b).

For example, if you define
identity x = x
then 
fmap identity :: Functor f => f b -> f b
(here a = b because identity :: p -> p )

Now, the type of (.) is;
(.) :: (b -> c) -> (a -> b) -> (a -> c)

if you write  fmap . fmap, in general (a priori) the type of the fmaps could be
FIRSTFMAP                 fmap :: Functor f1 => (d -> e) -> f1 d -> f1 e
SECONDFMAP            fmap :: Functor f2 => (g -> h) -> f2 g -> f2 h

let's see if there must be some bonds between types d,e,g,h, due to the type of (.)

(b -> c) = FIRSTFMAP (the first argument of (.) )
(a -> b) = SECONDFMAP  (the second argument of (.) )

so, we have (I'll not write "Functor f1" or "Functor f2", we know f1 and f2 are functors)

b = (d -> e)
c = (f1 d -> f1 e)
a = (g -> h)
b = (f2 g -> f2 h)

now, it must be b=b, so the type (d -> e) must be the same type of (f2 g -> f2 h)
So 
d = f2 g
e = f2 h

The result of  fmap . fmap, will be of type (a -> c) that is 
(g -> h) -> (f1 d -> f1 e) = (g -> h) -> f1 d -> f1 e
that, remebering the conditions on d and e, is
(g -> h) -> f1 (f2 g) -> f1 (f2 h)

which is the type you found on the book
(you only need to add that f1, f2 are Functors, and the names of f and g can of course be replaced with a and b)

Cheers,
Ut

2018-06-12 18:12 GMT+02:00 Marco Turchetto <[hidden email]>:
I'm reading the "Haskell programming" book and in chapter 16 about functors they combine two "fmap" with the "(.)" function.
I really don't understand how the type of "fmap . fmap" is "(Functor f2, Functor f1) => (a -> b) -> f1 (f2 a) -> f1 (f2 b)".

The thing that really freaks me out is that I thought that "(.)" arguments are ONLY two unary function.
Maybe there is some curring magic underline, there is someone that can explain to me how the type of "fmap . fmap" is derived from the type of "fmap" and "(.)"?


_______________________________________________
Beginners mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners



_______________________________________________
Beginners mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
Reply | Threaded
Open this post in threaded view
|

Re: fmap composition

Marco Turchetto
It's all clear as day.

Thanks

On Tue, 12 Jun 2018 at 19:35 Ut Primum <[hidden email]> wrote:
Hi,
as you probably know, fmap ha type 
fmap :: Functor f => (a -> b) -> f a -> f b
So, you can see fmap as a unary funcrion that takes an argument of type (a->b) and returns a result of type (f a -> f b).

For example, if you define
identity x = x
then 
fmap identity :: Functor f => f b -> f b
(here a = b because identity :: p -> p )

Now, the type of (.) is;
(.) :: (b -> c) -> (a -> b) -> (a -> c)

if you write  fmap . fmap, in general (a priori) the type of the fmaps could be
FIRSTFMAP                 fmap :: Functor f1 => (d -> e) -> f1 d -> f1 e
SECONDFMAP            fmap :: Functor f2 => (g -> h) -> f2 g -> f2 h

let's see if there must be some bonds between types d,e,g,h, due to the type of (.)

(b -> c) = FIRSTFMAP (the first argument of (.) )
(a -> b) = SECONDFMAP  (the second argument of (.) )

so, we have (I'll not write "Functor f1" or "Functor f2", we know f1 and f2 are functors)

b = (d -> e)
c = (f1 d -> f1 e)
a = (g -> h)
b = (f2 g -> f2 h)

now, it must be b=b, so the type (d -> e) must be the same type of (f2 g -> f2 h)
So 
d = f2 g
e = f2 h

The result of  fmap . fmap, will be of type (a -> c) that is 
(g -> h) -> (f1 d -> f1 e) = (g -> h) -> f1 d -> f1 e
that, remebering the conditions on d and e, is
(g -> h) -> f1 (f2 g) -> f1 (f2 h)

which is the type you found on the book
(you only need to add that f1, f2 are Functors, and the names of f and g can of course be replaced with a and b)

Cheers,
Ut

2018-06-12 18:12 GMT+02:00 Marco Turchetto <[hidden email]>:
I'm reading the "Haskell programming" book and in chapter 16 about functors they combine two "fmap" with the "(.)" function.
I really don't understand how the type of "fmap . fmap" is "(Functor f2, Functor f1) => (a -> b) -> f1 (f2 a) -> f1 (f2 b)".

The thing that really freaks me out is that I thought that "(.)" arguments are ONLY two unary function.
Maybe there is some curring magic underline, there is someone that can explain to me how the type of "fmap . fmap" is derived from the type of "fmap" and "(.)"?


_______________________________________________
Beginners mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners


_______________________________________________
Beginners mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners

_______________________________________________
Beginners mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners