Is it possible to define units of measure for kB, GB, … with explicit or implicit conversion?

谁说胖子不能爱 提交于 2019-12-04 05:51:30

问题


I would like to define a Measure type

[<Measure>] type kB

that converts to the number of bytes when explicitly cast to an int:

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

Since there is no way to add an explicit conversion operator to a type like in C#, I am stuck. Anyone has an idea? Even better would be an implicit conversion, so that when a function requires numbers of bytes, it can be called like

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

Special conversion functions do not appeal - writing a kB function is trivial but not as nice:

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

A conversion function that does the same with units is not cool either

7<kB> |> convertToByte

回答1:


Are active patterns "cool" enough for you?

[<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"



回答2:


The short answer to your question seems to be no. Which strikes me as add because this conversion is a bit shift. Alas, how about static methods as prescribed from "Programming 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


来源:https://stackoverflow.com/questions/32169761/is-it-possible-to-define-units-of-measure-for-kb-gb-with-explicit-or-impli

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!