我想以某种方式组合函数。请在伪代码(不是 F#)中考虑这两个函数
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
和那个 F1 requires 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
会改变第一行的打字?
提前感谢您的想法,
格特-扬
更新 两个(几乎)做所描述的事情。
一个使用元组。第二行看起来有点古怪,工作正常。小缺点是我现在不能使用柯里化,否则我将不得不添加更多古怪的代码。
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