dasskorpion
dasskorpion

Reputation: 87

Meaning of different lambda functions and characters

At the moment I am learning Haskell, but I am struggling with the syntax of a few example. What do they exactly mean?

First: What is the difference between these two lambdas (-> \y and y)?

lambda1 = \x -> \y -> x + y
lambda2 = \x y -> x + y

Second: What does this mean? Is this a lambda that act as a "pseudo" list generator that generates a list with 3 elements. How can I create such a list?

lambda3 = [\x -> x+1, \x -> 2*x, \x -> x^2]

Third: What does the \_ exactly mean?

lambda4 = \_ -> (\x -> x+1, \() -> 'a')

Upvotes: 2

Views: 313

Answers (4)

MathematicalOrchid
MathematicalOrchid

Reputation: 62808

There is no -> y. The correct way to read this is

(\ x -> (\ y -> (x + y)))

As it happens, Haskell has "curried functions", which means that

\ x y -> (x + y)

just happens to be equivalent to the above.


lambda3 is a list which contains three elements. Each of those elements happens to be a function. Functions are data in Haskell; you can pass them as arguments, return them as results, stuff them into lists, etc.

lambda3 = [ (\x -> x+1) , (\x -> 2*x) , (\x -> x^2) ]

lambda4 = \_ -> (\x -> x+1, \() -> 'a')

The "_" character basically means "I don't care what this is; ignore it". You can use it anywhere you can use a pattern. For example,

foobar x _ z = x + y

is a 3-argument function that completely ignores argument #2. Read about pattern matching and this should become clear. (I.e., it's not to do with lambdas, it's to do with patterns.)

Upvotes: 0

Hécate
Hécate

Reputation: 1035

First: What is the difference between these two lambdas (-> \y and y)?

There is no difference. Both produce the same output for the same input, and since they're pure functions, you can be sure that they produce no external effects that you wouldn't see.

The difference lies in that the first lambda uses syntactic sugar for currying. \x y -> x + y is equal to \x -> \y -> x + y. Now, don't you think it looks a lot like type signatures, such as foo :: Int -> Int -> Int ? ;) It means that the function foo takes 2 Int and produces an Int.

Since I don't have a very precise answer for the 2nd…

Third: What does the \_ exactly mean?

It's a lambda function (\) to which is associated the _ variable. _ is used as a placeholder to say “I don't care about the content of this variable, I'm even going to give it a proper name”.

Upvotes: 3

Jon Purdy
Jon Purdy

Reputation: 54971

lambda2 is syntactic sugar for lambda1. All of these are equivalent:

f = \x -> \y -> x + y
f = \x y -> x + y
f x = \y -> x + y
f x y = x + y
f x y = (+) x y
f x = (+) x
f = (+)

lambda3 is a list of unary functions on numbers. Each function has the type (Num a) => a -> a, so the list has type (Num a) => [a -> a]. You could produce a list of values from this with map or a list comprehension:

fs = [\x -> x+1, \x -> 2*x, \x -> x^2]

map (\f -> f 3) fs
map ($ 3) fs
[f 3 | f <- fs]
==
[4, 6, 9]

lambda4 uses pattern-matching syntax. For example, if you have a data type:

data Foo = Foo Int String

Then you can write a lambda that pattern-matches on it:

f = \ (Foo n s) -> concat (replicate n s)

f (Foo 3 "bar") == "barbarbar"

(But unlike case, there is no way to provide alternative patterns if Foo has multiple constructors.)

The _ pattern just says “accept a value and ignore it”, so lambda4 is a function that accepts an argument, ignores it, and returns a pair (2-tuple) of unary functions, the first of type (Num a) => a -> a and the second of type () -> Char, so its type is Num a => r -> (a -> a, () -> Char).

lambda4 = \_ -> (\x -> x+1, \() -> 'a')
lambda4 = \ignored -> (\x -> x+1, \() -> 'a')

(inc, getA) = lambda4 ()
inc 3 == 4
getA () == 'a'

Functions that ignore their arguments can be constructed with the const function, and operator sections ((+ 1)) are typically preferred over lambdas (\x -> x + 1), so you can also write the above as:

lambda4 = const ((+ 1), const 'a')

Upvotes: 10

soupi
soupi

Reputation: 1013

On your second question, lambda3 is just a bad variable name. this is a list of functions of type Num a => a -> a. You can verify that by typing the following in ghci:

:t [\x -> x+1, \x -> 2*x, \x -> x^2]

Upvotes: 3

Related Questions