2016-10-14 23 views
1

私はSMLで関数を定義する2つの方法があることに気付きました。アドイン機能を取る場合例えば、これらは2つの方法があります。SMLのint - > int - > intと(int * int) - > intの違いは何ですか?

:秒1のように、関数型を作成し

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

:として

fun add x y = x+y; 

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

は、第一の方法は、関数型を作成します

val add = fn : int * int -> int 

同じ機能のこれら2つのタイプの違いは何ですか?同じ機能に2つのタイプがあるのはなぜですか?

+0

int - > int - > intの場合、addが最初にintをとり、別のintをとり、final intを返す別の関数を返します。 –

+0

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

答えて

5

我々は、彼らがなるあなたの二つの定義から糖衣構文を削除する場合:最初のケースaddにそう

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

val add = fn xy => 
    case xy of 
     (x,y) => x+y 

引数xを取り、別の関数を返す関数でありますこれは引数yをとり、x+yを返します。別の関数を返すことによって複数の引数をシミュレートするこのテクニックは、カリングと呼ばれます。

addは、タプルを引数としてとり、タプルの2つの要素を追加する関数です。

これは、2つの異なるタイプについても説明します。 ->は、右に関連する関数矢印であり、int -> int -> intintを受け取り、int -> int関数を返す関数を記述するint -> (int -> int)と同じであることを意味します。一方

*タプルタイプに使用される構文であり、それはint * intでは、2つのint値を含むタプルの一種であるので、(*->より高い優先順位を有するので(int * int) -> intとして括弧れる)int * int -> intはかかる機能を説明します2つのintのタプルを返し、intを返します。

+0

はい、あなたは正しいです。 SMLでのカレーに関するこの有益な記事を見つけました。 https://courses.cs.washington.edu/courses/cse341/09au/notes/notes07.html –

0

これら2つの機能が異なる理由は、Curryingという現象のためです。具体的には、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 *) 

addCurryは「代替」に使用して変数を返すことができる形式にaddProdの減少であることを教えてくれる。したがって、addProdaddCurryは、Contextually-Equivalentです。ただし、それらはではありません。意味的に等価です。 (int*int)は製品タイプです。それは、input1=intinput2=intを期待していると言います。 int -> intは、intを返し、intを返します。これは矢型です。

2カレー風味

1))タプル - だから、fun addProd (x,y)(x,y)などを表します

あなたが興味を持っている場合、あなたはまた、SMLの関数の引数の唯一の2種類があることを知ってほしいこと関数の引数にタプルします。

関連する問題