Reputation: 1961
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
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
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