假设我有以下功能:
sumAll :: [(Int,Int)] -> Int sumAll xs = foldr (+) 0 (map f xs) where f (x,y) = x+y
结果sumAll [(1,1),(2,2),(3,3)]
将是12
.
我不明白的是(x,y)
价值来自哪里.嗯,我知道他们来自xs
变量,但我不明白如何.我的意思是,在没有where关键字的情况下直接执行上面的代码,它将是这样的:
sumAll xs = foldr (+) 0 (map (\(x,y) -> x+y) xs)
在顶级代码中,我无法理解f
变量和(x,y)
变量如何表示(\(x,y) -> x+y)
lambda表达式.
希望这会有所帮助.关键是f
应用于列表的元素,它们是成对的.
sumAll [(1,1),(2,2),(3,3)] -- definition of sumAll = foldr (+) 0 (map f [(1,1),(2,2),(3,3)]) -- application of map = foldr (+) 0 (f (1,1) : map f [(2,2),(3,3)]) -- application of foldr = 0 + foldr (+) (f (1,1)) (map f [(2,2),(3,3)]) -- application of map = 0 + foldr (+) (f (1,1)) (f (2,2) : map f [(3,3)]) -- application of foldr = 0 + (f (1,1) + foldr (+) (f (2,2)) (map f [(3,3)])) -- application of f = 0 + (2 + foldr (+) (f (2,2)) (map f [(3,3)])) -- application of map = 0 + (2 + foldr (+) (f (2,2)) (f (3,3) : map f [])) -- application of foldr = 0 + (2 + (f (2,2) + foldr (+) (f (3,3)) (map f []))) -- application of f = 0 + (2 + (4 + foldr (+) (f (3,3)) (map f []))) -- application of map = 0 + (2 + (4 + foldr (+) (f (3,3)) [])) -- application of foldr = 0 + (2 + (4 + f (3,3))) -- application of f = 0 + (2 + (4 + 6)) = 0 + (2 + 10) = 0 + 12 = 12
在Haskell中,函数是第一类数据类型.
这意味着您可以像其他类型的数据(如整数和字符串)一样传递函数.
在上面的代码中,您将'f'声明为一个函数,它接受一个参数a(两个值(x,y)的元组)并返回(x + y)的结果.
foldr是另一个函数,它接受3个参数,一个二进制函数(在本例中为+)一个起始值(0)和一个迭代器值的数组.
简而言之,'其中f(x,y)= x + y'只是缩写的缩写
sumAll :: [(Int,Int)] -> Int sumAll xs = foldr (+) 0 (map myFunctionF xs) myFunctionF :: (Int,Int) -> Int myFunctionF (x,y) = x + y
编辑:如果您不确定折叠器是如何工作的,请查看Haskell Reference Zvon 下面是foldl/map的示例实现.
foldl :: (a -> b -> b) -> b -> [a] -> b foldl _ x [] = x foldl fx (y:ys) = foldl f (f y x) ys map :: (a -> b) -> [a] -> [b] map _ [] = [] map f (x:xs) = (f x) : (map f xs)