3

我正在学习 F#,但我不明白类型推断和泛型在这种语言中是如何工作的。例如,我可以声明一个通用的 min 函数并将其与不同类型的参数一起使用:

let min a b = if a < b then a else b

let smallestInt = min 3 5
let smallestFloat = min 3.0 5.0

但是如果我用一个类型尝试同样的事情,它就行不通了:

type Point2D(x, y) = 
    member this.X = x
    member this.Y = y

let float32Point = new Point2D(0.0f, 1.0f)
let intPoint = new Point2D(0, 1) // This expression was expected to have type 
                                 // float32 but here has type int

所以,我有几个问题:

  • 为什么我可以为不同的类型重用泛型函数定义而不是类型定义?
  • 该函数是否像 C# 泛型一样在运行时专门针对每种类型?还是在编译时像 C++ 模板?或者是否执行拳击以将每个参数视为 IComparable?

谢谢。

4

1 回答 1

6

类需要显式类型参数。这有效:

type Point2D<'T>(x:'T, y:'T) = 
    member this.X = x
    member this.Y = y

let float32Point = Point2D(0.0f, 1.0f)
let intPoint = Point2D(0, 1)

要回答你的第二个问题,你的定义min有签名'a -> 'a -> 'a (requires comparison)comparison约束仅在编译时存在(运行时签名相同,减去约束)。

<替换为对 的调用GenericLessThanIntrinsic,该调用具有约束。约束仅传播给调用者。

此外,从规范的第 14.6.7 节:

泛化是在可能的情况下为定义推断泛型类型的过程,从而使构造可与多种不同类型重用。默认情况下,泛化应用于所有函数、值和成员定义,本节后面列出的情况除外。泛化也适用于在对象表达式中实现泛型虚方法的成员定义。

(重点补充)

请注意,列表中缺少类。我想它没有给出理由,但它设计使然。

于 2012-05-14T18:04:44.000 回答