我有点googlet,我还没找到我想要的东西。正如所料。我的问题是,是否可以定义一个F#管道占位符?我想要的是如下_中的_:
let func a b c = 2*a + 3*b + c
2 |> func 5 _ 6
评估为22(2 * 5 + 3 * 2 + 6)。
为了进行比较,请查看magrittr
R套餐:https://github.com/smbache/magrittr
答案 0 :(得分:6)
这是(不幸的是!)F#语言不支持 - 虽然您可以想出各种花哨的函数和运算符来模拟行为,但我认为重构代码通常更容易,因此调用不在管道。然后你可以写:
let input = 2
let result = func 5 input 6
管道的优势在于您有一个“主”数据结构,该结构通过一系列步骤处理(例如通过一系列List.xyz
函数处理的列表)。在这种情况下,管道使代码更好,更易读。
但是,如果您的函数需要多个输入而没有“主”输入(最后一个参数可以使用管道),那么使用临时变量和普通函数调用实际上更具可读性。
答案 1 :(得分:2)
我不认为这是可能的,但你可以简单地使用lambda表达式,比如
2 |> (fun b -> func 5 b 6)
答案 2 :(得分:1)
你可以使用这样的新功能:
let func a b c = 2*a + 3*b + c
let func2 b = func 5 b 6
2 |> func2
答案 3 :(得分:1)
这是一种无点的方法:
let func a b c = 2*a + 3*b + c
let func' = func 5 >> (|>) 6
let result = 2 |> func'
// result = 22
我已经详细解释了here。
但请注意,使用您的代码的人不会很快掌握您的意图。您可以将它用于学习语言的更深层次的目的,但在实际项目中,您可能会找到更适合的简单方法:
let func' b = func 5 b 6
答案 4 :(得分:0)
@Dominic Kexel对钱的权利。如果对象实际上不是在参数链中放置占位符,这可能是由lambda函数实现的,但是改变了它们的顺序,那么flip
的情况就比pipe
更多。 。
从简单的两参数案例
let flip f b a = f a b
// val flip : f:('a -> 'b -> 'c) -> b:'b -> a:'a -> 'c
我们需要派生一个函数
let flip23of3 f a c b = f a b c
// val flip23of3 : f:('a -> 'b -> 'c -> 'd) -> a:'a -> c:'c -> b:'b -> 'd
为了翻转第二个和第三个参数。这也可以写成
let flip23of3' f = f >> flip
let func a b c = 2*a + 3*b + c
2 |> flip23of3 func 5 6
// val it : int = 22
答案 5 :(得分:-1)
我自己试一试。结果并不完美,但它和我一样接近:
let (|.|) (x: 'a -> 'b -> 'c) (y: 'b) = fun (a: 'a) -> x a y
let func (a:string) b (c:int) = 2.*(float a) + b + 5.*(float c)
let foo = func "4" 9. 5
printfn "First: %f" foo
let bar =
"4"
|> ((func |.| 9.) |.| 5)
printfn "Second: %f" bar
let baz =
9.
|> (func "4" |.| 5)
printfn "Third: %f" baz
输出正如预期的那样
First: 42.000000
Second: 42.000000
Third: 42.000000