F#,Pipe-forward第一个参数

时间:2017-03-15 03:01:39

标签: f#

与此问题非常相似: F# pipe first parameter

我目前正在学习F#和函数式编程,我想知道是否有一种简单的方法来管道转发第一个参数(而不是最后一个参数)。

例如,如果我想管道最后一个参数,它看起来非常漂亮和干净:

[4;5;6]
    |> List.append [1;2;3]

// Result: [1;2;3;4;5;6]

如果我想管道转发第一个参数,我可以使用" fun x - >"功能,但我只是好奇,如果有一个更清洁的方式。

[1;2;3]
    |> fun x -> List.append x [4;5;6]

// Result: [1;2;3;4;5;6] 

非常感谢。

P.S。我的同事刚刚帮我解决了这个问题。但如果您对F#初学者有任何建议,我将不胜感激。谢谢。

4 个答案:

答案 0 :(得分:10)

当参数的顺序不方便时,您总是可以转换函数本身,使其以不同的顺序获取参数:

let flip f x y = f y x

[1; 2; 3]
    |> (flip List.append) [4; 5; 6]

转换函数在许多情况下都很有用。它是功能性程序员的面包和黄油。

但最后,我相信,可读性是最重要的:程序的阅读比它们写的更频繁。当我发现自己处于类似的情况,并且我不想为中间值命名或者出于某种原因使用lambda表达式时,我自己定义了一个直观易懂的函数:

let prependTo a b = List.append b a

[1; 2; 3] 
   |> prependTo [4; 5; 6]

答案 1 :(得分:9)

所有现有答案都能很好地解决问题。

但是,我认为如果你想使用管道来指定函数的第一个参数,大多数时候,这不是一个好主意,你应该只使用没有管道的普通调用:

List.append [1;2;3] [4;5;6]

原因是“管道模式”允许您编写对某些数据结构(列表等)执行一系列转换的代码。设计用于支持管道模式的库将把“主输入”作为支持管道的最后一个参数。

如果您输入的参数不是最后一个,则意味着您正在打破这种规律性,因此您不再通过一系列转换传递一个数据结构。这将使您的代码混乱,因为“它看起来像一个管道,但它不是真正的管道。”

当然,这不是始终的情况,并且在某些情况下你需要这个,但根据经验,我只会在适合时使用管道。

答案 2 :(得分:2)

只需使用lambda:

[1;2;3] |> fun l -> l @ [4;5;6]

或无点:

[1;2;3] |> (@) <| [4;5;6] // or
([1;2;3], [4;5;6]) ||> (@)

或作为正常功能:

let foo l = l @ [4;5;6]
let bar = foo [1;2;3]

答案 3 :(得分:1)

在询问我的同事之后,他建议:

[1;2;3]
    |> List.append
    <| [4;5;6]
// Result: [1;2;3;4;5;6]

如果您对像我这样的F#初学者有任何其他建议,我将非常感谢您的帮助。谢谢。