所以我有这个haskell代码,我理解其中的一半,但我无法理解这个\x ->
:
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
我理解longestProductLen
返回并且整数表示testDB
中最长的标题,然后它使用此整数来匹配k
中的formatLine
,但我无法理解它是如何与(Bardcode, Item)
匹配的,我想它与\x ->
有关,如果可以,请解释一下它是如何做到的?
谢谢!
答案 0 :(得分:9)
语法
function x y = <body>
相当于
function = \x y -> <body>
并称为lambda或匿名函数。编译器实际上将所有函数转换为lambda函数的赋值(第二种形式),因为它只是给函数值(函数是Haskell中的值)一个名称。
如果您将其视为另一个函数的参数,例如map
:
map (\x -> x + 1) [1, 2, 3]
这在语义上等同于
map add1 [1, 2, 3] where add1 x = x + 1
Lambdas也可以对其参数执行任意模式匹配。此外,如果您有像
这样的定义fib 0 = 1
fib 1 = 1
fib n = fib (n - 1) + fib (n - 2)
这相当于
fib = \n -> case n of
0 -> 1
1 -> 1
n -> fib (n - 1) + fib (n - 2)
因为编译器会首先将多个模式匹配转换为case语句,然后将其转换为将lambda指定给名称(在这种情况下将lambda指定为名称fib
)。
答案 1 :(得分:3)
这是Haskell的lambda抽象语法。 Haskell
\x -> e
对应数学
λx.e
在这种情况下,
\(x, y) -> length $ fst y
是一个函数,它接受一对(x,y)
并返回该对y
的第一个组件的长度。这是编写表达式的一种奇怪的方式;把它写成
\(x, (y1, y2)) -> length y1
或
length . fst . snd
为了保持一致。