Question

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 types of constraints can I specify with it?
  • Can I define my own kinds of constraints, like I can do with typeclasses in Scala?
Was it helpful?

Solution

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:

  1. yes the compiler will check this
  2. yes exactly, look at the F# specifications / Docu for more details
  3. 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>

OTHER TIPS

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
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top