Asik
Asik

Reputation: 22123

Type inference: functions vs types

I am learning F# and I don't understand how type inference and generics work in this language. For example, I can declare a generic min function and use it with parameters of different types:

let min a b = if a < b then a else b

let smallestInt = min 3 5
let smallestFloat = min 3.0 5.0

But if I try the same thing with a type, it doesn't work:

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

So, I have a few questions:

Thanks.

Upvotes: 3

Views: 229

Answers (1)

Daniel
Daniel

Reputation: 47914

Classes require explicit type parameters. This works:

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)

To answer your second question, your definition of min has the signature 'a -> 'a -> 'a (requires comparison). The comparison constraint exists only at compile-time (the run-time signature is the same, minus the constraint).

< is replaced with a call to GenericLessThanIntrinsic, which has the constraint. The constraint is merely propagated to callers.

Also, from section 14.6.7 of the spec:

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.

(emphasis added)

Notice, classes are missing from the list. I suppose it doesn't give the rationale, but it is by design.

Upvotes: 6

Related Questions