2017-01-31 43 views
3

我想理解這兩者之間的區別;sml理解函數組合

val my_fun = length o List.filter (fn (item) => item = #"a") o String.explode 

這一個可以調用(my_fun「名稱」將返回1),並正常工作。我想了解的功能組成的,爲什麼下面不工作

length o (List.filter (fn (item) => item = #"a") (String.explode "name")) 

定義在同級

f o g = f(g(x)) 

在第二種形式就是我們要做的是(我認爲)

length ([#"a"]) 
+0

您錯過了構圖定義中的參數; '(f o g)x = f(g x)',或'f o g = fn x => f(g x)'。 – molbdnilo

回答

3

你似乎將功能組合與功能應用混淆在一起。

組合物是高階函數,它接受兩個函數,fg和,兼容的類型的並返回另一個功能 - 它是通過首先施加到g的值,然後應用f到結果計算的功能。 o是一個內置的操作,但如果你想自己定義組成它會是這樣的

fun compose (f,g) x = f(g(x)) 

這有型fn : ('a -> 'b) * ('c -> 'a) -> 'c -> 'b(這正是當你在REPL鍵入(op o);你的類型)。請注意,compose的返回值是'c -> 'b,這是一個函數類型。

length o List.filter (fn (item) => item = #"a") o String.explode 

非常合理,因爲類型是兼容的,而且組合是右聯合的。

在另一方面,因爲你已經注意到,

length o (List.filter (fn (item) => item = #"a") (String.explode "name")) 

將相當於

length o [#"a"] 

這確實是沒有意義的。它甚至意味着用一個列表組成一個函數。列表不是一個函數。這是有道理的適用於length到這個列表,這是你所期望的。

應用僅僅是並列,因此,所有你需要做的是寫

長度(List.filter(FN(項目)=>項目=# 「A」)(String.explode 「名字」))

這就減少了length [#"a"]並從那裏到1

如果你想寫自己apply功能你可以這樣寫:

def apply f x = f x 

這可能會引起你表面上類似於compose但它的類型是根本不同的:fn : ('a -> 'b) -> 'a -> 'b。構成涉及申請,但它不是一回事。