Cette signature serait illégale dans .NET, de sorte que le seul moyen sera d'utiliser la fonction F # en ligne avec des contraintes statiques.
Vous pouvez alors définir une fonction comme ceci:
[<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
Le principal problème lorsqu'ils traitent avec des chiffres génériques et les unités de mesure que vous vous retrouvez avec les signatures où vous un avez un type générique avec un type paramètre (un higher kind) qui pour le moment ne sont pas pris en charge dans .NET.
MISE À JOUR
Après un certain temps, je courais aussi bien dans cette situation et a trouvé cette réponse qui arrive à venir de moi :)
Après essayer avec différentes unités de mesures que je compris qu'il n » t travail, car l'inférence de type ne généralise pas sur les unités de mesure, l'exemple affiché fonctionne parce que l'inférence de type témoigne de l'utilisation de la mesure M
, puis spécialise la fonction sur M
.
Mais est ici un moyen de le faire fonctionner, en utilisant explicitement l'opérateur $
défini ci-dessus:
[<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()
Il pourrait y avoir un moyen de créer une fonction générique, ou une constante générique, mais pour le moment il semble ne pas être possible avec la version actuelle de F #.
Je vais essayer avec F # 4.1 quand il est prêt.
Donc je ne peux pas avoir une fonction générique, mais plutôt une séquence de fonctions et je dois préciser laquelle je veux utiliser. Bien - pas encore ce que j'aimerais avoir, mais comme tu dis que c'est le meilleur que je peux actuellement obtenir, ça doit être suffisant. Merci beaucoup, monsieur :). –