Хорошо, вот еще один дубль, демонстрирующий, как вы можете объединить скалярную скорость и 2-мерное направление, чтобы реально использовать ваши единицы:
let vvector (velocity:float<'u>) (xydirection:float<rad>) =
{
X = cos (float xydirection) * velocity;
Y = sin (float xydirection) * velocity;
Z = 0.<_>
}
Что дает:
> vvector 15.3<m/s> angle<rad>;;
val it : Vector3<m/s> = {X = 13.4270132;
Y = 7.335210741;
Z = 0.0;}
Вы могли бы сделать шаг вперед, добавив оператор к вашему типу Vector3:
static member (*) (v1: Vector3<'u>, n: float<'v>) =
{ X = v1.X * n; Y = v1.Y * n; Z = v1.Z * n }
Что означало бы, что вы могли бы тогда сделать это:
let vvector2 (velocity:float<'u>) (xydirection:float<rad>) =
{ X = cos(float xydirection); Y = sin(float xydirection); Z = 0. } * velocity
Очевидно, вы все ещена самом деле «не» использовать ваши радианы, но это как бы ожидаемо, радианы в любом случае являются «не» единицами.Один из способов, которыми вы могли бы использовать их, - это если вы хотите иметь возможность управлять радианами и градусов.Вы можете добавить два других статических члена на свой Vector3:
static member ofAngle (ang:float<rad>) =
{ X = cos(float ang); Y = sin(float ang); Z = 0.0 }
static member ofAngle (ang:float<degree>) =
Vector3<'u>.ofAngle(ang * 2.<rad> * System.Math.PI / 360.<degree>)
Это выглядит красиво, но, к сожалению, не скомпилируется, потому что The method 'ofAngle' has the same name and signature as another method in this type once tuples, functions and/or units of measure are erased.
Вы можете проверить этот вопрос для более подробной информации.