As kvb explains in detail, the problem is that units of measure are a part of the type. This means that float | MPS of float v / 0.1 | MPS v -> v / 0.2.
As @kvb explains in detail, the problem is that units of measure are a part of the type. This means that float is different type than float (and unfortunately, this information isn't stored as part of the value at runtime). So, you're actually trying to write a function that would work with two different types of input.
The clean functional solution is to declare a discriminated union that can hold values of either the first type or the second type: type SomeValue = | M of float | MPS of float Then you can write the function using ordinary pattern matching: let convert v = match v with | M v -> v / 0.1 | MPS v -> v / 0.2 You'll need to explicitly wrap the values into the discriminated union value, but it's probably the only way to do this directly (without making some larger changes in the program structure). For normal types like int and float, you could also use overloaded members (declared in some F# type), but that doesn't work for units of measure, because the signature will be the same after the F# compiler erases the unit information.
There are two problems with your approach. First of all, when you use an underscore in the definition of your function, that's the same as using a fresh type variable, so your definition is equivalent to the following: let convert (v: float) = //' match v with | :? Float -> v / 0.1 | :?
Float -> v / 0.2 | _ -> failwith "unknown" What the error message is telling you is that the compiler know that v is of type float, and float has no proper subtypes, so there's no point in doing a type test to determine if it's a float or any other type. You might try to get around this by first boxing v into an object and then doing a type test. This would work, for instance, if you had a list and wanted to see if it were a list, because full type information about generic objects is tracked at runtime including generic type parameters (notably, this is different from how some other runtimes like Java's work).
Unfortunately, F# units of measure are erased at runtime, so this won't work here - there is no way for the system to infer the correct measure type given a boxed representation, since at runtime the value is just a plain float - F#'s system for units of measure is actually quite similar in this respect to how Java handles generic types. As an aside, what you're trying to do seems quite suspect - functions which are generic in the unit of measure shouldn't do different things depending on what the measure type is; they should be properly parametric. What exactly are you trying to achieve?
It certainly doesn't look like an operation which corresponds to physical reality, which is the basis for F#'s measure types.
Thanks for the answer. I will have to rethink my code once again. One comment: Why a value with units is not simplified into when using Microsoft.FSharp.Math.SI module?
– Oldrich Svec Apr 19 '10 at 10:16 1 @Oldrich - It's not clear to me why that's not simplified (my reading of the spec indicates that it should be), but F# is aware that those measures are equivalent (e.g. You can write let (x:float) = 1.0 and the compiler will allow it). It's possible that abbreviations such as Pa aren't always expanded out for display purposes. – kvb Apr 19 '10 at 10:57.
I cant really gove you an answer,but what I can give you is a way to a solution, that is you have to find the anglde that you relate to or peaks your interest. A good paper is one that people get drawn into because it reaches them ln some way.As for me WW11 to me, I think of the holocaust and the effect it had on the survivors, their families and those who stood by and did nothing until it was too late.