F#-如何方便地将列表中的元素应用于当前函数';s参数?
假设有一个列表:F#-如何方便地将列表中的元素应用于当前函数';s参数?,f#,F#,假设有一个列表: let lst = [1;2;3] 和一个curried函数: let addAll a b c = a + b + c 如何使用listlst中的元素方便地输入当前函数的参数 一种方法是: addAll (lst |> List.item 0) (lst |> List.item 1) (lst |> List.item 2) 但这并不能很好地扩展!而且,这很无聊。很难从有限的示例中说出您的实际用例是什么。列表被设计为包含不同数量的项,函数采用固
let lst = [1;2;3]
和一个curried函数:
let addAll a b c =
a + b + c
如何使用listlst
中的元素方便地输入当前函数的参数
一种方法是:
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
让lst=[1;2;3]
让我们把所有的东西都加起来=
a+b+c
设addAllVal=addAll
设f=addAllVal.GetType().GetMethod(“调用”[| typeof;typeof;typeof |])
让res=f.Invoke(addAllVal,Array.map框(Array.ofList lst)):?>int
从有限的示例中很难说您的实际用例是什么。列表被设计为包含不同数量的项,函数采用固定数量的项,因此两者不匹配。使用元组而不是列表可能更有意义:
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
让lst=[1;2;3]
让我们把所有的东西都加起来=
a+b+c
设addAllVal=addAll
设f=addAllVal.GetType().GetMethod(“调用”[| typeof;typeof;typeof |])
让res=f.Invoke(addAllVal,Array.map框(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
另一个选项是使用模式匹配:
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
就我所知,没有办法按你的要求去做。如果您始终应用相同的操作,通常的处理方法是在列表上进行折叠。我在想这可能是一个。你有什么特别想实现的吗?据我所知,没有办法做到你所要求的。如果您始终应用相同的操作,通常的处理方法是在列表上进行折叠。我在想这可能是一个。您是否特别希望实现某些目标?反射是动态解决此类问题的良好起点。我们可以编写一个实用函数来包装所有反射代码,然后在其他地方优雅地使用它。但是,正如您所建议的,反射可能很慢……反射是动态解决此类问题的一个良好起点。我们可以编写一个实用函数来包装所有反射代码,然后在其他地方优雅地使用它。然而,正如您所建议的,反射可能会很慢……这肯定是另一种选择。但它仍然是手动的,就像我的方法一样。绝对是另一种选择。但它仍然像我的方法一样是手动的。