From MSDN docs, the signature of List.max
is:
List.max : 'T list -> 'T (requires comparison)
My questions are:
- How does compiler statically verify that
'T
supports comparison operation? - Is
requires
a keyword to specify type constraints? If yes, what all typ开发者_C百科es of constraints can I specify with it? - Can I define my own kinds of constraints, like I can do with typeclasses in Scala?
take a look at this blog from Don Syme: Equality and Comparison Constraints in F#
you can think of those contraints as a form of type-classes light, normaly overriding Equals/GetHashCode and implementing IComparable is sufficient to use it in this cases.
To your questions:
- yes the compiler will check this
- yes exactly, look at the F# specifications / Docu for more details
- kind of - you can contraint to interfaces and that like - see the articles
PS: the (requires comparison) is defined by saying <'a when 'a : comparison>
in the context of a generic definition like
type MyType<'a when 'a : comparision>
Carsten's answer covers most of the bases. Regarding declaring the constraint, in most cases you don't need to declare it since it will be inferred by any use of a comparison operator. For instance:
let myListMax l = l |> List.reduce (fun x y -> if x > y then x else y)
// or myListMax l = l |> List.reduce max
As Carsten said, if you want to explicitly annotate the definition with the constraint you can do it like this:
let myListMax (l:'a list) : 'a when 'a : comparison = l |> List.reduce max
精彩评论