如何将值管道转移到函数的左侧参数?

ca9*_*3d9 9 f# f#-3.0

例如,

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
Run Code Online (Sandbox Code Playgroud)

怎么做fn 1 2

这只是测试的简化示例.我有一个复杂的函数返回一个值,我想将它管道转发到函数的左侧(而不是右侧).

pad*_*pad 10

我假设你至少有两个管道.否则,fn 1 2这项工作; 我们为什么要把它变得更复杂?

对于交换功能(满足f x y = f y x),例如(+),(*)等可以只使用1 |> fn 2.

对于其他功能,我可以看到一些替代方案:

  1. 使用后向管道

    arg1
    |> fn1
    |> fn2 <| arg2
    
    Run Code Online (Sandbox Code Playgroud)

    我倾向于小心使用它,因为运算符的优先级可能会导致一些微妙的错误.

  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
    
    Run Code Online (Sandbox Code Playgroud)

    它并不漂亮,但很明显,参数的顺序(/)被区别对待.

  3. 使用匿名函数funfunction关键字
    如果您需要模式匹配,这将非常方便.

    input
    |> createOption
    |> function None -> 0 | Some _ -> 1
    
    Run Code Online (Sandbox Code Playgroud)

IMO,你不必一直管道.创建一个更多的let绑定,然后你的意图是明确的,你可以避免由于不寻常的风格导致的错误.

let sum =
   Array.map2 (fun y d -> (y - d) ** 2.0) y d
   |> Array.sum
 sum / 2.0    
Run Code Online (Sandbox Code Playgroud)

  • +1"你不必一直管道":-)以及所有其他很好的选择. (4认同)

Joh*_*mer 5

这是一个看起来很漂亮的解决方案。我不知道这是否太实用

1 |> fn <| 2
Run Code Online (Sandbox Code Playgroud)

  • 我经常将其用于`defaultArg`。 (2认同)