2013-09-26 29 views
4

例如,如何將管道的值傳遞給函數的左側參數?

let fn x y = printfn "%i %i" x y 
1 |> fn 2 // this is the same as fn 2 1 instead of fn 1 2 

如何使它fn 1 2

這只是測試的簡化示例。我有一個複雜的函數返回一個值,我想將它向前推送到函數的左側(而不是右側)。

+2

通常的方法來改變鑽營爲了將管道進入一個匿名函數:|>有趣X - > FN×2 –

+2

這很可能會成爲一個很好的跡象,您應該切換參數的順序'fn'函數(除非你有其他需要傳遞第二個參數的管道)。 –

+0

我認爲托馬斯是正確的 - 我認爲這是一種氣味,應該告訴你,你可能想重新排序參數。 –

回答

7

我假設你至少有兩個管道。否則,fn 1 2會完成這項工作;爲什麼我們應該讓它更復雜?

對於可交換函數(滿足f x y = f y x)如(+)(*)等你可以只使用1 |> fn 2

對於其它功能,我可以看到幾個備選方案:

  1. 使用落後的管道

    arg1 
    |> fn1 
    |> fn2 <| arg2 
    

    我傾向於使用這種謹慎,因爲運營商的優先級可能會導致一些微妙的錯誤。

  2. 使用flip功能

    let inline flip f x y = f y x 
    
    Array.map2 (fun y d -> (y - d) ** 2.0) y d 
    |> Array.sum 
    |> flip (/) 2.0 
    

    它不漂亮,但很明顯,在(/)的參數順序區別對待。

  3. 使用匿名函數與funfunction關鍵字
    這是方便,如果你需要模式匹配到位。

    input 
    |> createOption 
    |> function None -> 0 | Some _ -> 1 
    

IMO,你不必管所有的方式。再創建一個let綁定,然後你的意圖很清楚,你可以避免由於不尋常的風格而造成的錯誤。

let sum = 
    Array.map2 (fun y d -> (y - d) ** 2.0) y d 
    |> Array.sum 
sum/2.0  
+3

+1,因爲「你不必一路走來走去」:-)以及所有其他偉大的選擇。 –

4

這是一個看起來很漂亮的解決方案。我不知道它是否太實際,但

1 |> fn <| 2 
+1

漂亮的+1。我不敢使用它。 – stmax

+2

我經常使用'defaultArg'。 – ildjarn

相關問題