繁体   English   中英

Haskell:翻转功能的目的?

[英]Haskell: Purpose of the flip function?

我有点意外,以前没有问过。 也许这是一个愚蠢的问题。

我知道翻转正在改变两个参数的顺序。

例:

(-) 5 3
= 5 - 3
= 2

flip (-) 5 3
= 3 - 5
= -2

但为什么我需要这样的功能呢? 为什么不手动更改输入?

为什么不写:

(-) 3 5
= 3 - 5
= -2

一个人不太可能在立即应用于两个或多个参数的函数上使用flip函数,但flip在两种情况下有用:

  1. 如果函数通过高阶传递给不同的函数,则不能简单地反转调用站点的参数,因为调用站点在另一个函数中! 例如,这两个表达式会产生非常不同的结果:

     ghci> foldl (-) 0 [1, 2, 3, 4] -10 ghci> foldl (flip (-)) 0 [1, 2, 3, 4] 2 

    在这种情况下,我们不能交换(-)的参数,因为我们不直接应用(-) ; foldl适用于我们。 所以我们可以使用flip (-)而不是写出整个lambda \\xy -> y - x

  2. 此外,使用flip将函数部分应用于其第二个参数可能很有用。 例如,我们可以使用flip来编写一个函数,该函数使用构建函数来构建无限列表,该函数在列表中提供了元素的索引:

     buildList :: (Integer -> a) -> [a] buildList = flip map [0..] 
     ghci> take 10 (buildList (\\x -> x * x)) [0,1,4,9,16,25,36,49,64,81] 

    也许更频繁地,当我们想要部分应用将使用更高阶的函数的第二个参数时使用它,就像在第一个示例中一样:

     ghci> map (flip map [1, 2, 3]) [(+ 1), (* 2)] [[2,3,4],[2,4,6]] 

    有时候,人们不会在这种情况下使用flip ,而是使用中缀语法,因为操作符部分具有唯一属性,可以为函数提供第一个第二个参数。 因此,写(`f` x)相当于写flip fx 就个人而言,我认为直接书写flip通常更容易阅读,但这是一个品味问题。

有时您会想通过提供第二个参数来使用函数,但是从其他地方获取第一个参数。 例如:

map (flip (-) 5) [1..5]

虽然这也可以写成:

map (\x -> x - 5) [1..5]

另一个用例是第二个参数很长时:

flip (-) 5 $
   if odd x
      then x + 1
      else x

但是你总是可以使用let表达式命名第一个参数计算,然后不使用flip

flip使用的一个非常有用的示例是按降序排序。 你可以在ghci看到它是如何工作的:

ghci> import Data.List

ghci> :t sortBy 
sortBy :: (a -> a -> Ordering) -> [a] -> [a]

ghci> :t compare
compare :: Ord a => a -> a -> Ordering

ghci> sortBy compare [2,1,3]
[1,2,3]

ghci> sortBy (flip compare) [2,1,3]
[3,2,1]

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM