f# - 类型推断 : functions vs types

标签 f#

我正在学习 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?

谢谢。

最佳答案

类需要明确的类型参数。这有效:

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 节:

Generalization is the process of inferring a generic type for a definition where possible, thereby making the construct reusable with multiple different types. Generalization is applied by default at all function, value, and member definitions, except where listed later in this section. Generalization also applies to member definitions that implement generic virtual methods in object expressions.

(强调)

注意,列表中缺少类。我想它没有给出基本原理,但设计的。

关于f# - 类型推断 : functions vs types,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10588506/

相关文章:

f# - 无法在 VS 代码上使用 FSI

concurrency - F# 在生成和终止进程方面真的比 Erlang 更快吗?

f# - 替换列表中元素周围范围内的值

f# - 在 FParsec 中解析数字

F# 参数传递

F#可选参数和重载替代方案

casting - 为什么不能在 F# 中添加 int 和 float 文字?

visual-studio - 使用Microsoft Visual Studio开发文本特定领域语言(DSL)

datetime - F# 中的 System.DateTime 格式

Azure 存储类型提供程序 : FS0039 on build but intellisense shows type as available