2016-10-14 172 views
1

我注意到在SML中有兩種定義函數的方法。例如,如果你把add函數,這是兩個方面:SML中int - > int - > int和(int * int) - > int有什麼區別?

val add = fn : int -> int -> int 

第二個創建函數類型:

fun add x y = x+y; 

fun add(x,y) = x+y; 

與第一種方法創建函數類型

val add = fn : int * int -> int 

這兩種類型對於相同功能有什麼區別?還有爲什麼有兩種類型的相同功能?

+0

在int - > int - > int的情況下,是因爲currying哪裏添加第一個接受一個int,返回另一個接受另一個int並返回final int的函數? –

+0

https://courses.cs.washington.edu/courses/cse341/09au/notes/notes07.html –

回答

5

如果我們從兩個定義中刪除語法糖它們變爲

val add = fn x => fn y => x+y 

val add = fn xy => 
    case xy of 
     (x,y) => x+y 
在第一種情況下 add

所以是一個函數,參數x並返回另一個功能,它採用參數y,然後返回x+y。這種通過返回另一個函數來模擬多個參數的技術被稱爲currying。

在第二種情況下,add是一個函數,它將一個元組作爲參數,然後添加元組的兩個元素。

這也解釋了兩種不同的類型。 ->是功能箭頭,它與右側關聯,意爲int -> int -> intint -> (int -> int)相同,其描述的功能需要使用int並返回int -> int函數。

在另一方面*是用於的元組類型的語法,即int * int由含有兩個整數,所以int * int -> int(其括號作爲(int * int) -> int因爲*具有比->更高的優先級)的元組的類型描述了一個函數,它兩個int的元組並返回一個int。

+0

是的,你是對的。發現這篇關於在SML中捲曲的有用文章。 https://courses.cs.washington.edu/courses/cse341/09au/notes/notes07.html –

0

2功能不同的原因是因爲Currying的現象。具體來說,柯里格是能夠使用dom(f) = R^{n}作爲函數編寫任何函數,從Rn時間的輸入。這基本上是通過確保每個輸入返回一個函數來接收下一個變量來實現的。這就是->符號所表示的內容 - 這是Curry-Howard Isomorphism的基本結果。所以:

fun addCurry x y = x + y (* int -> int -> int *) 
fun addProd (x,y) = x + y (* (int*int) -> int *) 

告訴我們,addCurryaddProd還原成可以用於「替代品」,並返回變量的形式。因此,addProdaddCurry是Context-Equivalent。但是,它們是而不是語義相同。 (int*int)是產品類型。它表示它期望input1=intinput2=intint -> int表示需要int並返回int。這是一個箭頭類型。

如果你有興趣,你可能也想知道,只有2個類型的參數來SML功能:

1)令行禁止

2)元組 - 那麼,fun addProd (x,y)代表(x,y)作爲元組到函數參數。

相關問題