Эта подпись была бы недопустимой в .NET, поэтому единственный способ - использовать встроенную функцию F # со статическими ограничениями.
Затем вы можете определить такую функцию:
[<Measure>]
type M = class end
let x = LanguagePrimitives.FloatWithMeasure<M> 2.
type T<[<Measure>]'M>() =
static member ($) (T, x) = LanguagePrimitives.FloatWithMeasure<'M> x
static member ($) (T, x) = LanguagePrimitives.Float32WithMeasure<'M> x
static member ($) (T, x) = LanguagePrimitives.Int32WithMeasure<'M> x
// more overloads
let inline NumberWithMeasure x = T() $ x
let a: float<M> = NumberWithMeasure 2.
let b: float32<M> = NumberWithMeasure 2.0f
let c: int<M> = NumberWithMeasure 2
Основная проблема при работе с общими числами и единицами измерения заключается в том, что вы получаете те сигнатуры, в которых у вас есть общий тип с параметром типа (a более высокий тип), которые в настоящий момент не поддерживаются в .NET.
ОБНОВЛЕНИЕ
Через некоторое время я тоже столкнулся с этой ситуацией и нашел ответ, который пришел от меня :)
Попробовав его с разными единицами измерения, я понял, что это не работает, потому что вывод типа не обобщает единицы измерения, опубликованный пример работает, потому что вывод типа свидетельствует об использовании с мерой M
, а затем специализирует функцию на M
.
Однако вот способ заставить его работать, явно используя оператор $
, определенный выше:
[<Measure>] type km
[<Measure>] type miles
type WithMeasure<[<Measure>]'M>() =
static member ($) (x, T) = LanguagePrimitives.FloatWithMeasure<'M> x
static member ($) (x, T) = LanguagePrimitives.Float32WithMeasure<'M> x
static member ($) (x, T) = LanguagePrimitives.Int32WithMeasure<'M> x
static member ($) (x, T) = LanguagePrimitives.DecimalWithMeasure<'M> x
static member ($) (x, T) = LanguagePrimitives.Int16WithMeasure<'M> x
static member ($) (x, T) = LanguagePrimitives.Int64WithMeasure<'M> x
static member ($) (x, T) = LanguagePrimitives.SByteWithMeasure<'M> x
// no more overloads
let a: float<km> = 2. $WithMeasure()
let b: float32<miles> = 2.0f $WithMeasure()
Может быть способ создать универсальную функцию или универсальную константу, но на данный момент это кажется невозможным с текущей версией F #.
Я попробую с F # 4.1, когда он будет готов.
person
Gus
schedule
28.02.2015