3

从 MSDN 文档中,签名List.max为:

List.max : 'T list -> 'T (requires comparison)

我的问题是:

  • 编译器如何静态验证是否'T支持比较操作?
  • requires指定类型约束的关键字吗?如果是,我可以用它指定哪些所有类型的约束?
  • 我可以定义自己的约束类型吗,就像我可以在 Scala 中使用类型类一样?
4

2 回答 2

5

看看 Don Syme 的这篇博客:F# 中的平等和比较约束

您可以将这些约束视为轻量级类型的一种形式,通常覆盖 Equals/GetHashCode 并实现 IComparable 足以在这种情况下使用它。

对于您的问题:

  1. 是的,编译器会检查这个
  2. 是的,请查看 F#规范/ Docu了解更多详细信息
  3. 有点——你可以限制接口之类的——见文章

PS:(需要比较)是<'a when 'a : comparison>在通用定义的上下文中定义的,例如

type MyType<'a when 'a : comparision>
于 2011-09-11T10:17:12.813 回答
2

卡斯滕的回答涵盖了大部分基础。关于声明约束,在大多数情况下,您不需要声明它,因为它将通过任何比较运算符的使用来推断。例如:

let myListMax l = l |> List.reduce (fun x y -> if x > y then x else y)
// or myListMax l = l |> List.reduce max

正如 Carsten 所说,如果你想用约束明确地注释定义,你可以这样做:

let myListMax (l:'a list) : 'a when 'a : comparison = l |> List.reduce max
于 2011-09-11T15:35:28.300 回答