southpaw93
southpaw93

Reputation: 1961

Meaning of backslash in Haskell code?

So I have this haskell code, and I understand half of it, but I can't get my head around this \x -> here:

testDB :: Catalogue
testDB = fromList [
 ("0265090316581", ("The Macannihav'nmor Highland Single Malt", "75ml bottle")),
 ("0903900739533", ("Bagpipes of Glory", "6-CD Box")),
 ("9780201342758", ("Thompson - \"Haskell: The Craft of Functional Programming\"", "Book")),
 ("0042400212509", ("Universal deep-frying pan", "pc"))
 ]


-- Exercise 1

longestProductLen :: [(Barcode, Item)] -> Int
longestProductLen = maximum . map (\(x, y) -> length $ fst y) 

formatLine :: Int -> (Barcode, Item) -> String
formatLine k (x, (y1, y2)) = x ++ "..." ++ y1 ++ (take  (k - length y1) (repeat '.')) ++ "..." ++ y2

showCatalogue :: Catalogue -> String
showCatalogue c = foldr (++) "" $ map (\x -> (formatLine (longestProductLen (toList testDB)) x) ++ "\n") $ toList c

I understand that longestProductLen returns and integer meaning the longest title in testDB and then it uses this integer to match k in formatLine, but I can't understnad how it matches (Bardcode, Item) and I guess it has something to do with \x ->, if it does can you please explain how it does that?

Thank you!

Upvotes: 10

Views: 13356

Answers (2)

bheklilr
bheklilr

Reputation: 54058

The syntax

function x y = <body>

Is equivalent to

function = \x y -> <body>

And is called a lambda or anonymous function. The compiler actually turns all your functions into assignments of lambda functions (the second form) since it's just giving a function value (functions are values in Haskell) a name.

If you see it given as an argument to another function like map:

map (\x -> x + 1) [1, 2, 3]

This is semantically equivalent to

map add1 [1, 2, 3] where add1 x = x + 1

Lambdas can perform arbitrary pattern matching on their arguments, too. Also, if you have a definition like

fib 0 = 1
fib 1 = 1
fib n = fib (n - 1) + fib (n - 2)

This is equivalent to

fib = \n -> case n of
    0 -> 1
    1 -> 1
    n -> fib (n - 1) + fib (n - 2)

Because the compiler will first translate the multiple pattern matching into a case statement, then convert it to assigning a lambda to a name (in this case assigning the lambda to the name fib).

Upvotes: 26

dfeuer
dfeuer

Reputation: 48580

That's Haskell's syntax for lambda abstraction. The Haskell

\x -> e

corresponds to the mathematical

λx.e

In this case,

\(x, y) -> length $ fst y

is a function that takes a pair (x,y) and returns the length of the first component of the pair y. This is a slightly odd way to write the expression; it would be better to write it as

\(x, (y1, y2)) -> length y1

or as

length . fst . snd

for consistency.

Upvotes: 8

Related Questions