这些haskell函数中的这些值来自哪里?

时间:2008-12-18 05:17:32

标签: haskell map lambda tuples fold

假设我有以下功能:

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表达式。

3 个答案:

答案 0 :(得分: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

答案 1 :(得分: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

修改:如果您不确定折叠器的工作方式,请查看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)

答案 2 :(得分:3)

不是答案,但我想我应该指出你的功能f:

f (x, y) = x + y

可以表示为

f = uncurry (+)