我想以某种方式组合函数。请考虑伪代码(而不是 F#)中的这 2 个函数
F1 = x + y
F2 = F1 * 10 // note I did not specify arguments for F1, 'reverse curry' for lack of a better word
我希望 F# 做的是弄清楚,因为
let F1 x y = x + y
//val F1 : int -> int -> int
代码let F2 = F1 * 10
会给我与 F1 相同的签名:val F2 : int -> int -> int
,并调用F2 2 3
结果是 50: (2 + 3) * 10。这相当聪明......
所发生的情况完全不同。第一行按预期进行:
let F1 x y = x + y
//val F1 : int -> int -> int
但是当我添加第二行时let F2 = F1 * 10
它抛弃了 F#。它抱怨说the type int does not match the type 'a -> 'b -> 'c
现在的F1requires member ( + )
.
我当然可以这样拼写:
let F1(x, y) = x + y
let F2(x, y) = F1(x, y) * 10
但现在我可能已经使用了 C#,我们已经不再那么遥远了。元组参数在很大程度上破坏了 F# 的优雅。另外,我的实际函数 F1 和 F2 的参数远多于 2 个,所以这让我眼花缭乱,这正是我想通过使用 F# 来避免的。这样说会更自然:
let F1 x y = x + y
let F2 = F1 * 10
有什么办法我可以(几乎)做到这一点吗?
额外加分:这些错误消息到底是怎么回事?为什么第二行let F2 = F1 * 10
改变第一个打字?
预先感谢您的想法,
Gert-Jan
update两种方法(几乎)可以实现所描述的功能。
一种使用元组。第二行第一行看起来有点古怪,但效果很好。小缺点是我现在不能使用柯里化,否则我将不得不添加更奇怪的代码。
let F1 (a, b) = a + b
let F2 = F1 >> (*) 10
F2(2, 3) // returns 50
另一种方法是使用记录。这更直接一些,乍一看更容易理解,但需要更多的代码和仪式。确实消除了 F# 的一些优雅,看起来更像 C#。
type Arg (a, b) =
member this.A = a
member this.B = b
let F1 (a:Arg) = a.A + a.B
let F2 (a:Arg) = F1(a) * 10
F2 (Arg(2, 3)) // returns 50