【问题标题】:Understanding the map function when the first argument uses flip理解第一个参数使用翻转时的映射函数
【发布时间】:2019-06-08 13:24:17
【问题描述】:

我正在从“Learn You a Haskell for Great Good!”中学习高阶函数!米兰利波卡。我知道翻转函数接受一个函数并返回一个与原始函数一样的函数,但前两个参数翻转了。

我不完全理解以下带有地图功能的示例的工作原理。

ghci> map (flip subtract 20) [1,2,3,4]
[19,18,17,16]

Map 接受一个函数并将其应用于列表的每个元素,从而生成一个新列表。但是由于翻转是函数映射,带有参数subtract 20 [1,2,3,4],结果函数会是20 subtract [1,2,3,4]吗?

我认为这是不正确的,因为只有在您输入 subtract 1 20 时才会产生像 19 这样的值。我不确定在上面的示例中如何使用减法来生成输出列表。

【问题讨论】:

  • 基本上flip 如果您可以使用函数的中缀表示法,则有时是不必要的。如`subtract` 20。所以你可以做map (`subtract` 20) [1,2,3,4]。或者更好map ((-) 20) [1,2,3,4]
  • 括号很重要——你不能“分解”(flip subtract 20)

标签: haskell functional-programming higher-order-functions


【解决方案1】:

不,这里map :: (a -> b) -> [a] -> [b] 采用的函数是(flip subtract 20),这是您传递给map 的参数。所以这意味着:

map (flip subtract 20) [1,2,3,4]

相当于:

[flip subtract 20 1, flip subtract 20 2, flip subtract 20 3, flip subtract 20 4]

flip :: (a -> b -> c) -> b -> a -> c 是一个函数,它接受一个函数并翻转参数。所以flip subtract 20 在语义上等价于\x -> subtract x 20。因此,我们的列表相当于:

[subtract 1 20, subtract 2 20, subtract 3 20, subtract 4 20]

subtract :: Num a => a -> a -> a(-) 的“翻转”版本,因此相当于:

[20 - 1, 20 - 2, 20 - 3, 20 - 4]

因此相当于:

Prelude> map (flip subtract 20) [1,2,3,4]
[19,18,17,16]

因此,上述表达式的较短版本是:

map (20 -) [1,2,3,4]

【讨论】:

    【解决方案2】:

    但是由于翻转是函数映射需要...

    没有。 map 将函数作为它的第一个参数 - 这里是 flip subtract 20。这确实是一个函数,我们现在将看到(如果不是,编译器会引发错误,因为它在这里期待一个函数)。

    我们将从subtract 开始 - 实际上定义为flip (-)。这意味着flip subtract 就是(-),或者:

    flip subtract = \a b -> a - b
    

    相对

    subtract = \a b -> b - a
    

    所以,通过柯里化:

    flip subtract a = \b -> a - b
    

    代入20:

    flip subtract 20 = \b -> 20 - b
    

    所以flip subtract 20 确实是一个函数,它返回从 20 中减去其参数的结果。mapping 这个函数在给定的列表上给出了显示的结果。

    【讨论】:

      【解决方案3】:

      flip 具有以下功能:它以相反的顺序(“翻转”)将给定函数应用于两个给定参数。

      Prelude> :t flip
      flip :: (a -> b -> c) -> b -> a -> c
      

      这就是(flip subtract 20) 变成函数 f(x) = 20-x 的方式,其中(subtract 20) 对应于 g(x) = x-20。

      然后,使用 map 函数将 f 应用于每个列表项。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-07-08
        • 1970-01-01
        • 2013-09-26
        • 2022-10-04
        相关资源
        最近更新 更多