【问题标题】:Where do theses values come from in this haskell function?这些值在这个 haskell 函数中来自哪里?
【发布时间】:2010-09-27 11:28:19
【问题描述】:

假设我有以下功能:

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

【问题讨论】:

    标签: haskell map lambda tuples fold


    【解决方案1】:

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

    f (x, y) = x + y
    

    可以表示为

    f = uncurry (+)
    

    【讨论】:

      【解决方案2】:

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

        在 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)
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2023-03-18
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-06-04
          • 2021-11-14
          • 1970-01-01
          相关资源
          最近更新 更多