Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does function composition (.) work from within?

I am studying Haskell. Currently, I am studying function composition. I understand (at least on a basic level) how function (.) can be used, but there are two things to it that I understand not.

So the function looks as follows:

(.) :: (b -> c) -> (a -> b) -> a -> c
f . g = \x -> f (g x)

First, the type declaration. (b -> c) -> (a -> b) essentially means that function f takes an argument from resulting value (b) of function g (which takes value a) and returns value of type c. I don't understand the following part -> a -> c, why should there be -> a there? Why is (b -> c) -> (a -> b) -> c wrong? From my point of view (which is obviously wrong), function g is already taking a as an argument.

Second, the body of the function f . g = \x -> f (g x). What does \x -> do here? Lambda is pretty straightforward. For example filter (\(a,b) -> a + b > 4) [(1,2),(3,4)], but a simple \x -> makes me stuck. I would probably write the body like this f . (g x) = f (g x) (which is obviously wrong again).

like image 536
Mitrael Kankan Avatar asked Mar 04 '23 11:03

Mitrael Kankan


1 Answers

(b -> c) -> (a -> b) -> c would be a function that takes two functions f :: b -> c and g :: a -> b, and somehow call g without an initial argument of type a.

For the second question, consider how you would define (.) using prefix notation instead. (It might be easier to see if we use a "regular" name for the function; I'll include that as a comment after each snippet of code):

(.) f g x = f (g x)    -- compose f g x = f (g x)

x is the "third argument" for (.), or more precisely the argument for the function returned by (.) f g. This is equivalent to defining (.) f g as a function directly, by putting a function on the right-hand side instead of the ultimate return value of that function:

(.) f g x =       f (g x)  -- Implicit function def: compose f g x =       f (g x)
(.) f g   = \x -> f (g x)  -- Explicit function def: compose f g   = \x -> f (g x)

You can also use parentheses to define the function implicitly:

(f . g) x = f (g x)
like image 200
chepner Avatar answered Mar 11 '23 18:03

chepner