首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Haskell:翻转功能的目的?

Haskell:翻转功能的目的?
EN

Stack Overflow用户
提问于 2018-07-01 06:22:00
回答 3查看 2.8K关注 0票数 9

我感到有点惊讶的是,以前没有人问这个问题。也许这是个愚蠢的问题。

我知道翻转改变了两个论点的顺序。

示例:

代码语言:javascript
复制
(-) 5 3
= 5 - 3
= 2

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

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

为什么不直接写:

代码语言:javascript
复制
(-) 3 5
= 3 - 5
= -2
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2018-07-01 06:41:45

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

  1. 如果该函数被传递到另一个函数的较高阶,则不能简单地反转调用站点上的参数,因为调用站点位于另一个函数中!例如,这两个表达式产生非常不同的结果: ghci> foldl (-) 0 1,2,3,4 -10 ghci> foldl (-)0 1,2,3,4 2 在这种情况下,我们不能交换(-)的参数,因为我们没有直接应用(-)foldl为我们应用了它。所以我们可以使用flip (-)而不是写出整个lambda \x y -> y - x
  2. 此外,使用flip对其第二个参数部分应用函数可能是有用的。例如,我们可以使用flip编写一个函数,该函数使用在列表中提供元素索引的构建器函数构建无限列表: buildList ::(整数-> a) -> a buildList =翻转映射0. ghci>取10 (buildList (\x -> x*x) 0,1,4,9,16,25,36,49,64,81 ) 也许更频繁的情况是,当我们希望部分地应用将被更高级别使用的函数的第二个参数时,就会用到这个参数,如第一个示例中所示: ghci>映射(翻转映射1,2,3) (+ 1),(* 2)2,3,4,2,4,6] 有时,人们不会在这种情况下使用flip,而是使用infix语法,因为运算符段具有唯一的属性,可以为函数提供第一个或第二个参数。因此,编写(`f` x)等同于编写flip f x。就我个人而言,我认为直接编写flip通常更容易阅读,但这是一个品味问题。
票数 20
EN

Stack Overflow用户

发布于 2018-07-01 07:00:17

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

代码语言:javascript
复制
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]
票数 5
EN

Stack Overflow用户

发布于 2018-07-01 06:46:57

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

代码语言:javascript
复制
map (flip (-) 5) [1..5]

虽然这也可以写成:

代码语言:javascript
复制
map (\x -> x - 5) [1..5]

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

代码语言:javascript
复制
flip (-) 5 $
   if odd x
      then x + 1
      else x

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

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51120910

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档