Aadit M Shah
Aadit M Shah

Reputation: 74244

What does the following lambda function in Haskell actually return?

Consider the following lambda function in Haskell:

(\x g n -> g (x * n))

It takes two parameters: a Num named x and a function g which takes a Num named n and returns something else. The lambda function returns another function of the same type as g:

(\x g n -> g (x * n)) :: Num a => a -> (a -> t) -> a -> t

What I don't understand is what does the expression g (x * n) actually represent. For example consider the following use case:

((\x g n -> g (x * n)) 2 id)

In this case x is 2 and g is id. However what is n? What does g (x * n) represent? By simple substitution it can be reduced to id (2 * n). Is this the same as id . (2 *)? If so then why not simply write (\x g -> g . (x *))?

Upvotes: 3

Views: 532

Answers (2)

rampion
rampion

Reputation: 89123

I'm going to contradict chirlu. (\x g n -> g (x * n)) is a function of one argument.

Because all functions only take one argument. It's just that that function returns another function, which returns another function.

Desugared, it's the same as

\x -> \g -> \n -> g (x * n)

Which is pretty close to its type

Num a => a -> (a -> b) -> a -> b

Expanding your use case:

(\x g n -> g (x * n)) 2 id

Let's expand that

(\x -> \g -> \n -> g (x * n)) 2 id

Which is the same as

((\x -> \g -> \n -> g (x * n)) 2) id

Now we can apply the inner function to its argument to get

(let x = 2 in \g -> \n -> g (x * n)) id

or

(\g -> \n -> g (2 * n)) id

Now we can apply this function to its argument to get

let g = id in \n -> g (2 * n)

or

\n -> id (2 * n)

Which, via inspection, we can state is equivalent to

\n -> 2 * n

Or, point-free

(2*)

Upvotes: 7

fredugolon
fredugolon

Reputation: 518

You're close. The last example you gave, ((\x g n -> g (x * n)) 2 id) represents a partial application of the function. It has a type signature of Num a => a -> t and is equivalent to the following: \n -> id (2 * n).

Upvotes: 1

Related Questions