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

发布于 2024-07-10 17:14:04 字数 519 浏览 6 评论 0 原文

假设我有以下函数:

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

Let's say I have the following function:

sumAll :: [(Int,Int)] -> Int
sumAll xs = foldr (+) 0 (map f xs)
  where f (x,y) = x+y

The result of sumAll [(1,1),(2,2),(3,3)] will be 12.

What I don't understand is where the (x,y) values are coming from. Well, I know they come from the xs variable but I don't understand how. I mean, doing the code above directly without the where keyword, it would be something like this:

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

And I can't understand, in the top code, how does the f variable and (x,y) variables represent the (\(x,y) -> x+y) lambda expression.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

夏了南城 2024-07-17 17:14:04

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

Hopefully this will help. The key is that f is applied to the elements of the list, which are pairs.

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
遥远的她 2024-07-17 17:14:04

在 Haskell 中,函数是第一类数据类型。

这意味着您可以像传递其他类型的数据(例如整数和字符串)一样传递函数。

在上面的代码中,您将“f”声明为一个函数,它接受一个参数 a(两个值 (x,y) 的元组)并返回 (x + y) 的结果。

foldr 是另一个函数,它接受 3 个参数、一个二元函数(在本例中为 +)、一个起始值 (0) 和一个要迭代的值数组。

简而言之,“where 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

Edit 的作用域简写:如果您不确定foldr 的工作原理,请查看 Haskell 参考 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)

In Haskell, functions are first class datatypes.

This means you can pass functions around like other types of data such as integers and strings.

In your code above you declare 'f' to be a function, which takes in one argumenta (a tuple of two values (x,y)) and returns the result of (x + y).

foldr is another function which takes in 3 arguments, a binary function (in this case +) a starting value (0) and an array of values to iterator over.

In short 'where f (x,y) = x + y' is just scoped shorthand for

sumAll :: [(Int,Int)] -> Int
sumAll xs = foldr (+) 0 (map myFunctionF xs)

myFunctionF :: (Int,Int) -> Int
myFunctionF (x,y) = x + y

Edit: If your unsure about how foldr works, check out Haskell Reference Zvon
Below is an example implementation of 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)
南风起 2024-07-17 17:14:04

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

f (x, y) = x + y

可以表示为

f = uncurry (+)

Not an answer, but I thought I should point out that your function f:

f (x, y) = x + y

can be expressed as

f = uncurry (+)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文