你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn

类型推理

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>()])