问题很简单,我希望对一些旅行费用进行一些计算,包括DKK和JPY的费用.因此,我找到了一种模拟货币的好方法,因此我能够来回转换:
[<Measure>] type JPY
[<Measure>] type DKK
type CurrencyRate<[<Measure>]'u, [<Measure>]'v> =
{ Rate: decimal<'u/'v>; Date: System.DateTime}
let sep10 = System.DateTime(2015,9,10)
let DKK_TO_JPY : CurrencyRate<JPY,DKK> =
{ Rate = (1773.65m<JPY> / 100m<DKK>); Date = sep10}
let JPY_TO_DKK : CurrencyRate<DKK,JPY> =
{ Rate = (5.36m<DKK> / 100.0m<JPY>); Date=sep10 }
Run Code Online (Sandbox Code Playgroud)
我继续将费用计算为记录类型
type Expense<[<Measure>] 'a> = {
name: string
quantity: int
amount: decimal<'a>
}
Run Code Online (Sandbox Code Playgroud)
在这里我有一个示例费用清单:
let travel_expenses = [
{ name = "flight tickets"; quantity = 1; amount = 5000m<DKK> }
{ name = "shinkansen ->"; quantity = 1; amount = 10000m<JPY> }
{ name = "shinkansen <-"; quantity = 1; amount = 10000m<JPY> }
]
Run Code Online (Sandbox Code Playgroud)
这就是节目停止的地方...... F#不喜欢那个列表,并抱怨所有列表都应该是DKK,这当然是有道理的.
然后我认为必须有一些聪明的方法来建立我的单位措施的区别联合,将它们放在一个类别中,然后我尝试:
[<Measure>] type Currency = JPY | DKK
Run Code Online (Sandbox Code Playgroud)
但这是不可能的,并导致The kind of the type specified by its attributes does not match the kind implied by its definition
.
到目前为止我提出的解决方案是非常多余的,我觉得这使得度量单位毫无意义.
type Money =
| DKK of decimal<DKK>
| JPY of decimal<JPY>
type Expense = {
name: string
quantity: int
amount: Money
}
let travel_expenses = [
{ name = "flight tickets"; quantity = 1; amount = DKK(5000m<DKK>) }
{ name = "shinkansen ->"; quantity = 1; amount = JPY(10000m<JPY>) }
{ name = "shinkansen <-"; quantity = 1; amount = JPY(10000m<JPY>) }
]
Run Code Online (Sandbox Code Playgroud)
有没有一种很好的方法来处理这些措施单位作为类别?比如说
[<Measure>] Length = Meter | Feet
[<Measure>] Currency = JPY | DKK | USD
Run Code Online (Sandbox Code Playgroud)
或者我应该改造我的问题,也许不使用计量单位?
关于第一个问题,你不能,但我认为你不需要在第二个问题中说明问题的单位.
想一想你如何计划在运行时获取这些记录(用户输入,从数据库,从文件......),并记住度量单位是编译时功能,在运行时擦除.除非这些记录总是硬编码,这将使您的程序无用.
我的感觉是你需要在运行时处理这些货币,并将它们视为数据更有意义.
尝试将字段添加到Expense
被叫货币:
type Expense = {
name: string
quantity: int
amount: decimal
currency: Currency
}
Run Code Online (Sandbox Code Playgroud)
然后
type CurrencyRate = {
currencyFrom: Currency
currencyTo: Currency
rate: decimal
date: System.DateTime}
Run Code Online (Sandbox Code Playgroud)