如何编写一个获得两个函数之和的函数?

时间:2018-10-04 07:39:45

标签: ocaml

我必须写一个代码来创建一个函数,假设“ f”计算两个函数的总和,假设“ h”和“ g”。我是这样写的:

let h x = x + 2;;
let g x = x + 4;;
let f h x g x = h x + g x;;

但是,当我输入f h 2 g 4;;时,它告诉我14错误,因为它应该显示12。为什么?

我还能以某种方式选择运行代码时要汇总哪些函数,还是需要每次都设置函数?

2 个答案:

答案 0 :(得分:5)

您正在遮盖x中的f参数,因此f h 2 g 4将得出h 4 + g 4。您需要做的就是将其他参数之一命名为y

let f h x g y = h x + g y;;

答案 1 :(得分:1)

如果我们从数学意义上讲“两个函数的和”,那么我们应该让一个函数接受两个参数gh,它们都是函数,并返回结果这也是一个函数(通常用g+h表示,并且(g+h)(x) = g(x) + h(x)这样)。

因此,目标是编写一个像这样的函数sum

let sum g h =
    ...

返回一个带有参数x并返回f(x) + g(x)的函数。

一个人可以这样:

let sum g h =
    fun x -> (g x) + (h x)

您可以检查sum的类型:

val sum : ('a -> int) -> ('a -> int) -> 'a -> int = <fun>

这意味着:

  • 它接受('a -> int)类型的第一个参数(该函数接受一个参数并返回一个整数:我们称为g的那个),

  • 它还需要一个第二个参数,类型也为('a -> int)(我们称为h),

  • 它还涉及'a -> int类型的函数,这也是我们想要的(因为g+h实际上是一个带有参数并返回整数的函数。

在大多数编程语言中,您将不得不具有这种函数定义。在OCaml中,多亏了currying和一些黑魔法,您才可以说“但是,等一下,您决定对最后一个'a -> int进行分组,并称返回类型为sum,但是难道不是'asum的第三个参数,它的返回类型就是int“?就像说我们可以将sum“ functor”作为一个以gh作为其参数并返回一个新函数的函数一样,该函数在调用{{ 1}},将返回x,但我们可以等效地将其视为具有三个参数g(x)+h(x)gh并返回x的函数。这两个愿景在OCaml中是等效的。因此,我们可以使代码更简单,只需编写:

g(x)+h(x)

您可以验证其类型仍为

let sum g h x = (g x) + (h x)

符合预期。


从那里您可以享受语法乐趣,并为函数定义自己的sum运算符,例如val sum : ('a -> int) -> ('a -> int) -> 'a -> int = <fun>

++

然后在定义let (++) g h x = (g x) + (h x) g之后使用它:

h

这将返回let g = ( ( + ) 5 ) and h = ( ( * ) 2 ) in (g ++ h) 3