kaf*_*fka 8 ocaml functional-programming function-composition
如何在函数式语言中定义复合函数,特别是使用Ocaml?例如,如果我编写一个计算另一个函数结果否定的函数,那就是:not(f(x))where f(x)返回一个布尔值.我该如何定义它?
Jef*_*ado 12
给定一些函数f,它具有以下类型:
f: 'a -> bool
Run Code Online (Sandbox Code Playgroud)
你希望能够生成另一个函数来包装它来否定结果.让我们考虑这个新函数的类型,让我们调用它negated(我没有使用,not因为它是内置函数的名称):
negated: ('a -> bool) -> 'a -> bool
Run Code Online (Sandbox Code Playgroud)
这是什么类型的?为什么不'a -> bool呢?记住,我们希望这个新函数接受现有函数并返回一个具有相同类型的新函数.为了更清楚地看到它,你可以这样想:('a -> bool) -> ('a -> bool)它是等价的.
那么现在给出这些约束,我们如何编写negated函数?
let negated f = ??
Run Code Online (Sandbox Code Playgroud)
那么我们首先要考虑这个函数需要返回一个函数:
let negated f = (fun x -> ??)
Run Code Online (Sandbox Code Playgroud)
接下来是什么?好吧,我们知道我们创建的新函数应该使用参数调用包装函数并取消它.让我们这样做,用参数调用函数:f x,并否定它:not (f x).这给了我们最终的函数定义:
let negated f = (fun x -> not (f x))
Run Code Online (Sandbox Code Playgroud)
让我们看看它的实际效果:
# let f x = x < 5;;
val f : int -> bool = <fun>
# f 2;;
- : bool = true
# f 8;;
- : bool = false
# let negated f = (fun x -> not (f x));;
val negated : ('a -> bool) -> 'a -> bool = <fun>
# let g = negated(f);;
val g : int -> bool = <fun>
# g 2;;
- : bool = false
# g 8;;
- : bool = true
Run Code Online (Sandbox Code Playgroud)
我不确定你到底要走多远 - 你写的代码会正常工作.因此,我将逐步介绍如何从头开始编写这些内容.简单的否定只是:
let not = function
| true -> false
| false -> true
Run Code Online (Sandbox Code Playgroud)
你可以如何写not (f x),它会给你否定结果f x.
对于组合函数的函数,您可以使用:
let comp f g x = f (g x)
Run Code Online (Sandbox Code Playgroud)
那么我们可以这样做:
let even n = match n mod 2 with
| 0 -> true
| _ -> false
let odd = comp not even
Run Code Online (Sandbox Code Playgroud)
哇,所有这些过于复杂的答案是什么?有什么问题:
let compose f g x = g (f x)
Run Code Online (Sandbox Code Playgroud)
为了让您的g(x) = not(f(x)),假设你有一个f : 'a -> bool:
let g = compose not f
Run Code Online (Sandbox Code Playgroud)
此外,你可以做一些很酷的事情,比如:
let composite_function =
let id x = x in
let transforms = [
(fun n -> n + 1);
(fun n -> n * 2);
(fun n -> n * n)
] in
List.fold_left compose id transforms
Run Code Online (Sandbox Code Playgroud)
现在composite_functionhas type int -> int,其有效定义为:
let composite_function n =
let n2 = (n + 1) * 2 in
n2 * n2
Run Code Online (Sandbox Code Playgroud)
编辑:哦,我猜查克确实这样做了。我可能不应该只是略读。无论如何,我碰巧喜欢折叠 compose 函数,所以我会继续这样做。:p