从 MSDN 文档中,签名List.max
为:
List.max : 'T list -> 'T (requires comparison)
我的问题是:
- 编译器如何静态验证是否
'T
支持比较操作? - 是
requires
指定类型约束的关键字吗?如果是,我可以用它指定哪些所有类型的约束? - 我可以定义自己的约束类型吗,就像我可以在 Scala 中使用类型类一样?
从 MSDN 文档中,签名List.max
为:
List.max : 'T list -> 'T (requires comparison)
我的问题是:
'T
支持比较操作?requires
指定类型约束的关键字吗?如果是,我可以用它指定哪些所有类型的约束?看看 Don Syme 的这篇博客:F# 中的平等和比较约束
您可以将这些约束视为轻量级类型的一种形式,通常覆盖 Equals/GetHashCode 并实现 IComparable 足以在这种情况下使用它。
对于您的问题:
PS:(需要比较)是<'a when 'a : comparison>
在通用定义的上下文中定义的,例如
type MyType<'a when 'a : comparision>
卡斯滕的回答涵盖了大部分基础。关于声明约束,在大多数情况下,您不需要声明它,因为它将通过任何比较运算符的使用来推断。例如:
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