類型推斷

Q#的類型推斷演算法是以針對 Hindley-Milner 類型系統設計的推斷演算法為基礎。 雖然最上層可呼叫者必須使用明確的類型批註宣告,但大部分在可呼叫者中使用的類型都可以推斷。 例如,假設有下列可呼叫專案:

function Length<'a>(xs : 'a[]) : Int
function Mapped<'a, 'b>(f : 'a -> 'b, xs : 'a[]) : 'b[]

和這個表示式:

Mapped(Length, [[], ["a"], ["b", "c"]])

然後,要 Length 的類型自變數會推斷為 Length<String[]>,而要 Mapped 的類型自變數則會推斷為 Mapped<String[], Int>。 不需要明確寫入這些類型。

模棱兩可的類型

有時候沒有可以推斷類型變數的單一主體類型。 在這些情況下,類型推斷失敗,並出現參考模棱兩可類型的錯誤。 例如,稍微變更上一個範例:

Mapped(Length, [[]])

[[]]的類型為何? 在某些類型系統中,可以將類型提供給 ∀a. a[][],但 Q#中不支援此功能。 需要具象類型,但有無限數目的類型可以運作:String[][](Int, Int)[][]Double[][][]等等。 您必須明確指出您的意思是哪一種類型。

根據情況,有多種方式可以執行這項作。 例如:

  1. 使用類型自變數呼叫 Length

    Mapped(Length<String>, [[]])
    
  2. 使用第一個類型自變數呼叫 Mapped。 (第二個類型自變數的 _ 表示仍應推斷它。

    Mapped<String[], _>(Length, [[]])
    
  3. 將空陣列常值取代為對連結庫函式的明確型別呼叫。

    Mapped<String[], _>(Length, [EmptyArray<String>()])