2015-08-23 2 views
0

Je voudrais définir une mesure de typeEst-il possible de définir des unités de mesure pour kB, GB, ... avec conversion explicite ou implicite?

[<Measure>] type kB 

qui convertit le nombre d'octets lorsque explicitement jeté un int:

(int)7<kB> // would result 1024kB - explicit would be fine 

Comme il n'y a aucun moyen d'ajouter une conversion explicite opérateur à un type comme en C#, je suis coincé. Quelqu'un a une idée? Mieux encore serait une conversion implicite, de sorte que lorsqu'une fonction exige un nombre d'octets, il peut être appelé comme

Allocate(7<kB>) // implicit would be superfine 

fonctions de conversion spéciales ne fait pas appel - écriture d'une fonction kB est trivial, mais pas aussi belle :

let kB(n) = 1024 * n 
kB(7) 
7 |> kB 

Une fonction de conversion qui fait la même chose avec des unités est pas cool soit

7<kB> |> convertToByte 
+0

Peut-être que vous avez choisi cette option? https://dotnetfiddle.net/KgaqqL –

+0

Je * pense * (mais je ne suis pas sûr) que c'est impossible et il semble que cette question soit proche de l'esprit de [celui-ci] (http://stackoverflow.com/q/ 21862335/1180426). Il y a un hack là qui pourrait vous aider, mais dans l'ensemble, il semble qu'il n'y ait pas d'approche réalisable. Aussi, [voici un lien de la réponse] (http://trelford.com/blog/post/Units-of-measure-auto-conversion.aspx) avec une autre approche, mais ce n'est pas sans un coût par rapport aux unités nues de mesure. –

+0

@ PatrykĆwiek thx beaucoup, oui tout a été dit. – citykid

Répondre

1

Les modèles actifs sont-ils assez "cool" pour vous?

[<Measure>] type kB 

// single case active pattern to convert from kB to raw B value 
let (|Bytes|) (x : int<kB>) = int(x * 1024) 

// use pattern matching in the declaration 
// val printBytes : int<kB> -> unit 
let printBytes (Bytes(b)) = 
    printfn "It's %d bytes" b 

printBytes 7<kB> 
// "It's 7168 bytes" 
+0

bien, c'est une version délicate d'un appel de fonction. – citykid

+0

Comment rendre gB et tB également disponibles? –

0

La réponse courte à votre question semble être non. Ce qui me frappe, c'est que cette conversion est un peu décalée. Hélas, que diriez-vous des méthodes statiques prescrites dans "Programmation f # 3.0" page 108?

[<Measure>] 
type B = 
    static member toKB (x: int<B>) = 
     1<KB> * x/1024<B> 

and [<Measure>] KB = 
    static member toB (x: int<KB>) = 
     x * 1024<B>/1<KB> 

let b1 = 1024<B> 
let kb1 = B.toKB b1