6

我googlet了一下,我还没有找到我要找的东西。正如预期的那样。我的问题是,是否可以定义 F# 管道占位符?我想要的是以下内容中的 _ :

let func a b c = 2*a + 3*b + c

2 |> func 5 _ 6

这将评估为 22 (2*5 + 3*2 + 6)。

为了比较,请查看magrittrR 包:https ://github.com/smbache/magrittr

4

6 回答 6

6

F# 语言不支持(不幸的是!) - 虽然您可以提出各种花哨的函数和运算符来模拟行为,但我认为重构代码通常更容易,以便调用在管道之外。然后你可以写:

let input = 2
let result = func 5 input 6

管道的优势在于您拥有一个通过一系列步骤处理的“主要”数据结构(例如通过一系列List.xyz函数处理的列表)。在这种情况下,管道使代码更美观、更易读。

但是,如果您的函数接受多个输入并且没有“主”输入(可用于管道的最后一个参数),那么使用临时变量和普通函数调用实际上更具可读性。

于 2014-02-15T14:37:24.207 回答
2

我认为这是不可能的,但你可以简单地使用 lambda 表达式,比如

2 |> (fun b -> func 5 b 6)
于 2014-02-14T12:46:28.637 回答
1

这是一个无点的方法:

let func a b c = 2*a + 3*b + c
let func' = func 5 >> (|>) 6
let result = 2 |> func'
// result = 22

我已经在这里详细解释了。

但是请注意,使用您的代码的人不会很快掌握您的意图。您可以使用它来学习语言的更深层次,但在实际项目中,您可能会发现一种更适合的简单方法:

let func' b = func 5 b 6
于 2014-02-14T14:50:31.447 回答
1

您可以使用这样的新功能:

let func a b c = 2*a + 3*b + c
let func2 b = func 5 b 6

2 |> func2
于 2014-02-14T13:06:57.793 回答
0

@Dominic Kexel 是正确的。如果对象实际上不是在参数链中放置占位符,这可以通过 lambda 函数实现,但改变它们的顺序,那么它更像是flipthan 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
于 2014-02-14T18:35:07.097 回答
-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
于 2014-02-14T13:51:11.153 回答