3

假设我有以下功能:

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

4

3 回答 3

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
于 2008-12-18T05:41:11.637 回答
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)
于 2008-12-18T05:31:08.067 回答
3

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

f (x, y) = x + y

可以表示为

f = uncurry (+)
于 2008-12-19T22:15:08.783 回答