F#:可以在运行时动态绑定度量单位吗?
我对 F# 非常陌生,对测量单位功能很感兴趣,并且大致了解它的正常工作原理,但想知道是否可以将测量值绑定到我们不知道测量值的值直到代码执行?
我正在查看的实际示例是将浮点数绑定为货币值,其中度量单位是从数据库查找中推断出来的。
假设每种货币(美元、欧元、澳元等)的度量值都是正常声明的:
[<Measure>] USD
[<Measure>] EUR
[<Measure>] AUD
...
首先,您需要一种从标识符获取度量值类型的方法,最好是度量值名称本身,因为货币代码很可能被存储和以 3 个字符的字符串形式检索(类似于 Enum.Parse()
)。
然后,您需要一种将浮点值绑定到上一步中创建的类型的方法。
这是可能的,还是有其他方法可以达到相同的结果?
I'm very new to F# and am intrigued by the Units of Measure functionality and have a rough idea of how it works normally, but would like to know if it's possible to bind measures to values where we don't know what the measure will be until the code is executing?
The practical example I'm looking at is binding floats as currency values where the unit of measure is inferred from a database lookup.
Let's assume that the measures for each currency (USD, EUR, AUD, etc) are declared normally:
[<Measure>] USD
[<Measure>] EUR
[<Measure>] AUD
...
First you would need a way to obtain a measure's type from an identifier, ideally the measure name itself as the currency code is most likely stored and retrieved as a 3-character string (similar to Enum.Parse()
).
Then you would need a way of binding a float value to the type created in the previous step.
Is this possible, or is there another way to achieve the same outcome?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这是不可能的,因为 F# 测量单位被删除(它们仅存在于编译时)。
您可以编写一个具有运行时实现的库(我没有考虑过设计会是什么样子)。但你可能会失去静态检查。
我认为更好的策略可能是隔离边界,并在边界点(从数据库读取并推断单元类型的位置)以某种方式将正确的类型放入类型系统中,但这取决于代码的结构和方式你到底在做什么,这可能或可能不可能/容易......
This isn't possible, since F# units-of-measure are erased (they only exist at compile-time).
You could author a library with a runtime implementation (I haven't thought about what a design would look like). But you probably lose the static checking.
I think possibly a better strategy may be to isolate the boundary, and at the boundary point (where you read from the database and infer the unit types) somehow get the right types into the type system, but depending on how the code is structured and what exactly you're doing, that may or may not be possible/easy...
除非您正在编写实际上特定于一种特定货币的代码,否则您不应在代码中明确提及美元、欧元、澳元等。相反,使您的代码对所涉及的货币具有多态性。
您必须考虑的是您期望从计量单位获得什么样的安全性。例如,如果(在非常简单的场景中)您将从数据库字段中读取数据,进行一些处理并写回同一字段,然后使用
float<'a> 类型的函数-> float<'a>
正是您想要的:您不在乎货币是什么,只要您返回的货币与您输入的货币相同即可。Unless you are writing code that is actually specific to one particular currency, you shouldn't explicitly mention USD, EUR, AUD etc in your code. Instead, make your code polymorphic over the currency/currencies involved.
What you have to think about is what kinds of safety you are expecting to get from units of measure. If for example (in a very simplistic scenario) you would be reading from a database field, doing some processing and writing back to that same field, then having a function of type
float<'a> -> float<'a>
is exactly what you want: you don't care what the currency is, so long as you get back the same one you put in.