假设有一个列表:
let lst = [1;2;3]
和一个咖喱函数:
let addAll a b c =
a + b + c
如何使用 list 中的元素方便地输入curriedlst函数的参数?
一种方法是:
addAll (lst |> List.item 0) (lst |> List.item 1) (lst |> List.item 2)
但这并不能很好地扩展!还有,很无聊。
假设有一个列表:
let lst = [1;2;3]
和一个咖喱函数:
let addAll a b c =
a + b + c
如何使用 list 中的元素方便地输入curriedlst函数的参数?
一种方法是:
addAll (lst |> List.item 0) (lst |> List.item 1) (lst |> List.item 2)
但这并不能很好地扩展!还有,很无聊。
从有限的示例中很难说出您的实际用例是什么。列表旨在包含不同数量的项目,而函数采用恒定数量的项目,因此两者不能很好地匹配。使用元组而不是列表可能更有意义:
let tup = (1,2,3)
let addAll (a, b, c) =
a + b + c
addAll tup
元组包含固定数量的项目,但它们可以很容易地构造和解构,并允许您一次将所有参数传递给您的函数。
您也可以按照您的要求执行有关使用反射的操作,但这可能会在 F# 的未来版本中中断,并且对于像这样的简单案例来说,它几乎从来都不是一个好的设计。它也很慢,从下投和拳击的数量可以看出,它也不是很安全:
let lst = [1;2;3]
let addAll a b c =
a + b + c
let addAllVal = addAll
let f = addAllVal.GetType().GetMethod("Invoke", [| typeof<int>; typeof<int>; typeof<int> |])
let res = f.Invoke(addAllVal, Array.map box (Array.ofList lst)) :?> int
另一种选择是使用模式匹配:
let lst = [1;2;3]
match lst with [ a ; b; c] -> addAll a b c |_-> 0
返回6。如果 lst 没有恰好 3 个元素,则它会返回0,但您可以更改它以处理其他情况:
let callAddAll lst =
match lst with
| [ ] -> 0
| [ a ] -> addAll a 0 0
| [ a ; b ] -> addAll a b 0
| [ a ; b ; c ] -> addAll a b c
| a :: b :: c :: rest -> addAll a b c // ignore rest
[ ] |> callAddAll |> printfn "lst = %d" // = 0
[1 ] |> callAddAll |> printfn "lst = %d" // = 1
[1;2 ] |> callAddAll |> printfn "lst = %d" // = 3
[1;2;3 ] |> callAddAll |> printfn "lst = %d" // = 6
[1;2;3;4] |> callAddAll |> printfn "lst = %d" // = 6