Tom W
Tom W

Reputation: 5403

Why can't I pass arguments with units to F# types?

Suppose I have defined a unit of measure:

[<Measure>] type Blob

And I want a type that takes a value in Blobs per second as a constructor argument:

type Something(flowRate:double<Blob/s>) = ...

F# throws a wobbly on this - "double does not expect any type arguments, but here is given 1 type argument"

I understand the message. I'd have thought it was obvious what I was trying to do, though I acknowledge that the syntax probably is verifiably wrong. Question is, how do I express this relationship in code?

Upvotes: 6

Views: 248

Answers (1)

kvb
kvb

Reputation: 55184

As the message (sort of) indicates, doubles aren't measure-generic. Try float<Blob/s> instead. It's a bit strange, since float is a type synonym for type double. However, type float<[<Measure>]'t> is in some ways its own separate type. A similar problem occurs with single vs. float32, int32 vs. int, and int8 vs. byte. Section 9.7 of the spec partly covers this information.

It's especially confusing since you can't define your own types which differ only in their measure arity:

type T = class end
type T<[<Measure>]'t> = class end //' Duplicate definition of type T

Upvotes: 8

Related Questions