Can you summarize the following document?
        
  在大多數的程式語言中,所有值都有一個型別,它描述特定值的資料種類。在一些語言中,表示式的型別只在執行時才知道;這些語言被稱作動態型別語言。而另一些語言中,表示式的型別在編譯時就知道,這些語言叫做靜態型別語言。在靜態型別語言中,函式的輸入和輸出與區域性變數的型別一般必須用型別標註明確的提供。例如,在 C 語言中:  這個函式定義開始處,codice_1 宣告瞭 codice_2 是函式,接受一個整數型別的引數,並返回一個整數。codice_3 宣告瞭區域性變數 codice_4 是個整數。在支援型別推論的建議的語言中,程式碼可寫為如下:  這看起來非常像在動態型別語言中寫出的程式碼,但是提供了一些額外的約束(見下)使得能夠在編譯時推斷出所有變數的型別。在上面的例子中,因為codice_5 總是接受兩個整數並返回一個整數。編譯器可以推論出 codice_6 的值是個整數,因此 codice_4 是個整數,codice_2 的返回值是個整數。類似的,因為 codice_5 要求它的兩個實際引數都是整數,codice_10 必須是整數,因此 codice_2 接受一個整數實際引數。  但是在隨後一行中 "result2" 加上了一個浮點數 "codice_12",導致了 codice_10 同時用於整數和浮點數的衝突。這種情況將生成編譯時間錯誤訊息。在老語言中,"result2" 可以被隱含的宣告為浮點變數,通過隱含的轉換表示式中的整數 codice_10,簡單的因為小數點意外的被放到了整數 1 的後面。這種情況說明了二者之間的區別,“型別推論”不涉及型別轉換,而“隱含型別轉換”經常沒有限制的把資料強制成高精度的資料型別。

  型別推論指的是要麼部分要麼完全自動演繹的能力,把值的型別從表示式的最終計算中推匯出來。因為這個過程在編譯時間系統性的進行,編譯器經常能推出變數的型別或函式的型別標署,而不用給出明確的型別標註。在很多情況下,如果推論系統足夠強壯或程式足夠簡單,有可能完全從程式中省略型別標註。  要獲得正確推匯出缺乏型別標註的一個表示式的型別所必要的資訊,編譯器要麼隨著給它的子表示式(它們自身可以是變數或函式)的型別標註的聚集(aggregate)和後續簡約來收集這種資訊,要麼通過各種原子值的型別的隱含理解(比如 () : 單位; true : 布林; 42 : 整數; 3.14159 : 實數; 等等)。通過表示式的最終簡約到隱含型別原子值的識別,型別推論語言的編譯器有能力編譯完全沒有型別標註的程式。在高階程式設計和多型性的高度複雜的情況下,編譯器不能總是如此推論,偶爾需要型別標註來去除歧義。

  例如,考慮 Haskell 函式 codice_15,它把一個函式應用於一個列表的每個元素上,它可定義為:  明顯的函式 codice_15 接受一個列表作為第二個實際引數,它的第一個實際引數 codice_17 是可以應用於這個列表的元素的型別上函式,而 codice_15 的結果被構造為其元素是 codice_17 的結果的一列表。所以假定列表包含同樣型別的元素,我們能可靠的構造出型別標署 這裡的語法 "codice_20" 指示接受 codice_21 作為它的形式引數並生成 codice_22 的一個過程。 "codice_23" 等價於 "codice_24"。  注意 codice_15 的推論型別是引數化多型的: 實際引數和 codice_17 的結果的型別是不推出的,而是留作型別變數,所以 codice_15 可以應用於各種型別的函式和列表,只要在每次呼叫中實際型別是匹配的。

  進行型別推論的常用演算法是 Hindley–Milner 或 Damas–Milner 演算法。  這個演算法的起源是 Haskell B. Curry 和 Robert Feys 在1958年為簡單型別lambda演算設計的型別推論演算法。在 1969 年 Roger Hindley 擴充套件了這項工作並證明他們的演算法總能推出最一般的型別。在 1978 年 Robin Milner,獨立於 Hindley 的工作,提供了等價的演算法。在 1985 年 Luis Damas 最終證明了 Milner 的演算法是完備的並擴充套件它來支援帶有多型引用的系統。

  演算法過程分兩個步驟。首先需要生成一些要解的方程,接著解它們。

  用來生成方程的演算法類似與正規的型別檢查器,所以我們首先如下有型別lambda演算的正規型別檢查器:  formula_1  和  formula_2  這裡的 formula_3 是原始表示式 (比如 "3") 而 formula_4 是原始型別 (比如 "Integer")。  我們希望構造有型別 formula_5 的一個函式 formula_6,這裡的 formula_7 是型別環境而 formula_8 是一個項。我們假定這個函式已經定義在原始表示式上。其他情況有:  注意我們至今沒有指定在不能滿足各種條件的時候做什麼。這是因為,在簡單型別檢查演算法中,檢查在任何事情出錯的時候都失敗。  現在,我們開發一個更復雜的演算法來處理型別變數和在它們上的約束。所以,我們擴充套件原始型別的集合 T 來包括變數的無限補給,指示為小寫希臘字母 formula_17。詳情參見 。

  解方程通過合一進行。這是個意外簡單的演算法。函式 formula_18 運算在型別方式上並返回叫做“代換”的一個結構。代換簡單是一從型別變數到型別的一個對映。代換可以用明顯的方式組成和擴充套件。  合一方程的空集是足夠容易的: formula_19,這裡的 formula_20 是同一代換。  合一變數與型別以如下方式進行: formula_21,這裡的 formula_22 是代換合成運算元,而 formula_23 是保持約束 formula_24 於應用到它的新代換 formula_25 的集合。  當然 formula_26。  有趣的情況保持為 formula_27。
型別推論、型別推導、型別推斷、或隱含型別,是指程式語言中在編譯期自動推匯出值的資料型別的能力,它是一些強靜態型別語言的特性。一般而言,函數語言程式設計語言具有此特性。自動推斷型別的能力讓很多程式設計任務變得容易,讓程式設計師可以忽略型別標註的同時仍然允許型別檢查。