Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does the second parameter become a list of functions?

I am playing a bit with zipWith and encounter following:

Prelude Control.Applicative> :t zipWith id
zipWith id :: [b -> c] -> [b] -> [c]

Why does the compiler expect for the next argument a list of functions?

I tried to analyze, but could not conclude, why the next argument must be a list of functions.

How did the signature is getting apply, when I pass id to zipWith?

like image 663
softshipper Avatar asked Aug 04 '17 14:08

softshipper


1 Answers

The type of zipWith is:

zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]

And the type of id is:

id :: d -> d

So if we now want to derive the type of zipWith id, we push the type of id :: d -> d into the type of the first argument of zipWith:

  d -> d
~ a -> (b -> c)

So that means that: a ~ d and a ~ b -> c. So that means that the type of zipWith id is now:

   zipWith id :: [a] -> [b] -> [c]
-> zipWith id :: [b -> c] -> [b] -> [c]

How does this work: the first list has to contain a list of functions f :: b -> c, and the second list, a list of elements x :: b, and it thus calculates a list of elements f x :: c.

For example:

Prelude> zipWith id [(+1),(5/),(3*),(3-)] [1,4,2,5]
[2.0,1.25,6.0,-2.0]

since 1+1 is 2.0, 5/4 is 1.25, 3*2 is 6.0 and 3-5 is -2.0.

So zipWith id will take two elements f and x, and apply id f x on these, or more verbose (id f) x. Since id f is f, it will thus calculate f x.

We can thus conclude that zipWith is an elementwise mapping.

like image 190
Willem Van Onsem Avatar answered Sep 22 '22 15:09

Willem Van Onsem