Умножение векторов на единицу измерения в F#
Вопрос
Я написал следующее
[<Measure>]
type m
[<Measure>]
type s
[<Measure>]
type v = m/s
type Vector3<[<Measure>] 'a> =
{
X : float<'a>
Y : float<'a>
Z : float<'a>
}
static member (*)
(v:Vector3<'a>,f:float<'b>):Vector3<'a*'b> =
{ X = v.X*f; Y = v.Y*f ; Z = v.Z * f}
Теперь я пытаюсь использовать это таким образом:
let next_pos (position:Vector3<m> , velocity: Vector3<m/s> ,dt : float<s> -> Vector3<m>) =
position + (velocity * dt)
Это дает мне ошибку компилятора, но я почти уверен, что единица измерения выражена правильно. Какая моя ошибка?
Решение
Синтаксис, который вы пытались использовать для указания типа возврата, был неверным. Это должно выглядеть так:
let next_pos (position:Vector3<m>, velocity:Vector3<m/s>, dt:float<s>) : Vector3<m> =
position + (velocity * dt)
Чтобы указать, что функция возвращает значение типа Vector3<m>
, вам нужно добавить аннотацию типа к результату, который делается путем написания let foo <arguments> : T = <expr>
. Анкет При добавлении аннотаций типа к параметрам их необходимо в скобках (поэтому синтаксис не является неоднозначным). Как отметил Паоло в комментарии, вы используете ->
говорил это dt
это функция, потому что аннотация float<s> -> Vector3<m>
был прикреплен к параметру dt
.
Чтобы сделать компиляцию кода, мне также пришлось добавить реализацию (+)
оператор на ваш Vector3
, но я предполагаю, что у вас уже есть (и просто оставили его при публикации вопроса).
Другие советы
Я решил таким образом (но я не уверен насчет причины).
let next_pos (position:Vector3<m> , velocity: Vector3<m/s> ,dt : float<s> ) =
position + (velocity * dt)
Кажется, что компилятор не удается, если я отчетливо определяю тип возврата. Если я удалю, это, кажется, в состоянии сделать вывод правильного типа в любом случае. Но почему это?
В дополнение к этому, существуют ситуации, в которых имени столкновения в объявлении типа заставляют меня объяснить, указать тип возврата. Так что я не думаю, что это правильное решение в конце.