给出此表达式:
// val fn1 : a:'a -> b:'b -> c:'c -> d:'d -> e:'e -> f:'f -> g:'g -> unit
// val fn2 : a:'a -> b:'b -> c:'c -> d:'d -> e:'e -> f:'f -> g:'g -> unit
type T =
| A
| B
// val t : T
// val a : 'a
// val b : 'b
// val c : 'c
// val d : 'd
// val e : 'e
// val f : 'f
// val g : 'g
match t with
| A -> fn1 a b c d e f g
| B -> fn2 a b c d e f g
在调用支持currying的函数时,是否有不重复相同参数链的方法?所以你可以写一些像这样的奇怪的东西
(a, b, c, d, e, f, g)
|||||||> (match t with A -> fn1 | B -> fn2)
是否会出现匿名记录的情况?实现此目的的常见做法是什么?
仅应用而不是管道?
(match t with
| A -> curried1
| B -> curried2
) 1 2 3 4
FSharp闭包被实现为FSharpFunc<T, TResult>
,它具有一个invoke方法,使您无需多个部分应用程序即可调用该方法。
我不建议这样做,但是在极端情况下,您可以使用反射来调用带有参数数组的函数。
let funInvoke fn args =
let fnType = fn.GetType()
if not (FSharpType.IsFunction fnType) then
failwith "Not a function"
let invoke = Array.head (fnType.GetMethods())
invoke.Invoke(fn, args)
然后
funInvoke curried1 [|1; 2; 3 ; 4 |]
@ Asti的两种解决方案都可以正常工作。我将进一步简化第一个步骤。我更喜欢命名事物,这样我就可以记住它们的含义,所以我会写:]
let funcToCall = match t with | A -> curried1 | B -> curried2 funcToCall 1 2 3 4
但是,我认为注释中有一个有效的观点是您有太多参数。在这种情况下,使用命名记录更有意义:
type FuncParams = { Doors:int; Windows:int; Walls:int; Chimneys:int; .... }
let arg = { Doors=1; Windows=2; Walls=3; Chimneys=4; ... }
match t with A -> curried1 arg | B -> curried2 arg