[英]Haskell: Purpose of the flip function?
我有點意外,以前沒有問過。 也許這是一個愚蠢的問題。
我知道翻轉正在改變兩個參數的順序。
例:
(-) 5 3
= 5 - 3
= 2
flip (-) 5 3
= 3 - 5
= -2
但為什么我需要這樣的功能呢? 為什么不手動更改輸入?
為什么不寫:
(-) 3 5
= 3 - 5
= -2
一個人不太可能在立即應用於兩個或多個參數的函數上使用flip
函數,但flip
在兩種情況下有用:
如果函數通過高階傳遞給不同的函數,則不能簡單地反轉調用站點的參數,因為調用站點在另一個函數中! 例如,這兩個表達式會產生非常不同的結果:
ghci> foldl (-) 0 [1, 2, 3, 4] -10 ghci> foldl (flip (-)) 0 [1, 2, 3, 4] 2
在這種情況下,我們不能交換(-)
的參數,因為我們不直接應用(-)
; foldl
適用於我們。 所以我們可以使用flip (-)
而不是寫出整個lambda \\xy -> y - x
。
此外,使用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.