2008-12-18 93 views
3

比方说,我有以下功能:这些haskell函数的值来自哪里?

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变量,但我不明白如何。我的意思是,做上面的代码的情况下直接将其中的关键字,这将是这样的:

sumAll xs = foldr (+) 0 (map (\(x,y) -> x+y) xs) 

而且我不明白,在上面的代码,请问f变量和(x,y)变量代表(\(x,y) -> x+y) lambda表达式。

回答

5

在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 

编辑速记:如果您不确定foldr相似的工作方式,检查了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) 
6

希望这会有所帮助。关键是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 
3

不是一个答案,但我想我应该指出的是,你的函数f:

f (x, y) = x + y 

可以表示为

f = uncurry (+)