Есть две проблемы с вашим подходом. Прежде всего, когда вы используете подчеркивание в определении вашей функции, это то же самое, что и переменная нового типа, поэтому ваше определение эквивалентно следующему:
let convert (v: float<'u>) = //'
match v with
| :? float<m> -> v / 0.1<m>
| :? float<m/s> -> v / 0.2<m/s>
| _ -> failwith "unknown"
Сообщение об ошибке говорит о том, что компилятор знает, что v
имеет тип float<'u>
, а float<'u>
не имеет правильных подтипов, поэтому нет смысла проводить проверку типа, чтобы определить, является ли он float<m>
или любой другой тип.
Вы можете попытаться обойти это, сначала поместив v
в объект, а затем выполнив проверку типа. Это будет работать, например, если у вас есть list<'a>
и вы хотите узнать, был ли он list<int>
, потому что полная информация о типах универсальных объектов отслеживается во время выполнения, включая параметры универсального типа (в частности, это отличается от того, как некоторые другие среды выполнения, такие как работа Java). К сожалению, единицы измерения F # стираются во время выполнения, поэтому здесь это не сработает - система не может определить правильный тип меры при представлении в штучной упаковке, поскольку во время выполнения это значение просто float
- Система F # для единиц измерения на самом деле очень похожа на то, как Java обрабатывает универсальные типы.
Кроме того, то, что вы пытаетесь сделать, кажется довольно подозрительным - функции, которые являются общими в единице измерения, не должны делать разные вещи в зависимости от типа меры; они должны быть правильно параметрическими. Что именно вы пытаетесь достичь? Это, конечно, не похоже на операцию, которая соответствует физической реальности, которая является основой для типов измерений F #.