簡體   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