F# - splat/解包参数列表

标签 f#

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])

或者 apply(func_name, args_list) 函数
apply(add, [1, 2, 3])

最佳答案

对于配对和三合会,有预定义的运算符 ||> , <|| , |||><|||类似于 |><|对于单个参数(单体):

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

关于F# - splat/解包参数列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32138221/

相关文章:

c# - 大型 float 列表的查找函数 - 内存计算?

f# - DU 案件名称

arrays - F#查找2个数组/列表之间的丢失元素

f# - 在F#中匹配数组

f# - 使用 FParsec 解析分隔列表

f# - 添加 View 对话框在引用 F# 项目的 MVC 5 项目中不起作用

c# - 如何在 F# 中实例化类及其属性

f# - Action 和 unit -> F# 中的 unit 类型之间的重载解析不明确

f# - 是否可以在运行时获取联合体的标签?

f# - 在 FsUnit F# for XUnit 中断言异常