2011-02-14 73 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