2011-02-14 76 views
8

如何定义函数式语言中的复合函数,特别是Ocaml?例如,如果我编写计算另一个函数结果的否定的函数,即:not(f(x))其中f(x)返回布尔值。我怎样才能定义它?ocaml中的复合函数

回答

12

鉴于一些功能f,具有类型:

f: 'a -> bool 
要能产生另一个函数来包装它否定结果

。让我们看看这个新功能的类型,让我们把它negated(我不使用not,因为它是一个内置的名称):

negated: ('a -> bool) -> 'a -> bool 

为什么是这样的类型?为什么不是'a -> bool?请记住,我们希望这个新函数接受一个现有的函数,并返回一个具有相同类型的新函数,它会做一些不同的事情。为了更清楚地看到它,你可以这样想:('a -> bool) -> ('a -> bool)这相当于。

所以现在给了这些限制,我们该怎么写negated函数呢?

let negated f = ?? 

嗯,我们首先要考虑的是这个函数需要返回一个函数:

let negated f = (fun x -> ??) 

下一步是什么?那么,我们知道我们创建的新函数应该用参数调用我们的包装函数,否定它。让我们这样做,用参数调用函数:f x,否定它:not (f x)。这给了我们最终的功能定义:

let negated f = (fun x -> not (f x)) 

让我们来看看它在行动:

# 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 
5

我不知道你要找究竟有多远去这里 - 你写的代码将工作精细。所以我会简单介绍一下你如何从头开始编写这些东西。简单的否定就是:

let not = function 
    | true -> false 
    | false -> true 

如何编写not (f x),它会给你的f x结果的否定。

对于构成函数的函数,你可以使用:

let comp f g x = f (g x) 

然后我们可以这样做:

let even n = match n mod 2 with 
    | 0 -> true 
    | _ -> false 

let odd = comp not even 
+0

我们可以将`comp`定义为运算符,例如:let($)f g = function x - > f(g x)let odd = not $ even` – ygrek 2011-02-15 08:39:02

3

哇,所有这些过于复杂的答案是什么?出了什么问题:

let compose f g x = g (f x) 

为了让您的g(x) = not(f(x)),假设你有一个f : 'a -> bool

let g = compose not f 

此外,你可以做很酷的东西,如:

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 

现在composite_function具有类型int -> int,其有效定义为:

let composite_function n = 
    let n2 = (n + 1) * 2 in 
    n2 * n2 

编辑:哦,我想查克其实是这么做的。我可能不应该只是剔除。在任何情况下,我都喜欢折叠撰写功能,所以我会保持这种状态。 :p