使用柯里化多次传递相同的参数链
Passing the same chain of parameters multiple times with currying
给出这个表达式:
// 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
有没有办法在调用支持柯里化的函数时不重复相同的参数链?所以你可以写一些像这样的奇怪的东西
(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
给出这个表达式:
// 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
有没有办法在调用支持柯里化的函数时不重复相同的参数链?所以你可以写一些像这样的奇怪的东西
(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