F#内置运算符/函数是否允许解压缩参数列表/元组并将其传递给函数调用?
使用示例:
// simple add function
let add (a1 : int) (a2 : int) (a3 : int) = a1 + a2 + a3
// what I want to achieve
let result = add (missing_operator)[1; 2; 3]
// or
let result' = add (missing_operator) (1, 2, 3)
// flattening list
let a = [1; 2; 3]
let b = [(missing_operator) a; 4; 5]
与Python *运算符类似
def add(a1, a2, a3):
return a1 + a2 + a3
add(*[1,2,3])
或者应用(func_name,args_list)函数
apply(add, [1, 2, 3])
答案 0 :(得分:10)
对于成对和三合一,预定义的运算符||>
,<||
,|||>
和<|||
类似于|>
和<|
论证(monuple):
let add a b c = a + b + c
add <||| (1, 2, 3)
(1, 2, 3) |||> add
您可以自己添加此类操作符:
let (||||>) (a1, a2, a3, a4) func = func a1 a2 a3 a4
let foo u v x y = ( u + v ) * ( x + y )
(1, 2, 3, 4) ||||> foo
所有这些操作符也适用于非均匀类型。
如果您想放弃类型安全,以下工作(对于非空参数):
let invokeWith args op =
let func = op.GetType().GetMethod("Invoke", args |> Array.map(fun a -> a.GetType()))
func.Invoke(op, args)
add |> invokeWith [|1; 2; 3|]
也适用于非均匀参数类型:
let pad (a : string) l = a.PadRight(l)
pad |> invokeWith [| "a"; 12 |]
当然,一旦你放弃静态类型检查,你就可以独立完成了:
// compiles but throws at runtime
pad |> invokeWith [| "a"; None |]
,而
// does not compile
// ( "a", None ) ||> pad
答案 1 :(得分:3)
我认为在F#中这样做的一种惯用方法可能是这样的:
// simple add function
let add (a1 : int) (a2 : int) (a3 : int) = a1 + a2 + a3
// what I want to achieve
let result = match [1; 2; 3] with | [a;b;c] -> add a b c // pattern matching works on lists
// or
let result' = let (a,b,c) = (1, 2, 3) in add a b c // unpacking tuples
// flattening list
let a = [1; 2; 3]
let b = // sequence expressions with yield!
seq {
yield! a
yield 4
yield 5
} |> Seq.toList
let c = [4; 5]
let b' =
seq {
yield! a
yield! c
} |> Seq.toList