7

我正在尝试使用协议来创建工程编号类型(“knumber”),所以我可以说(+ "1k" "2Meg")并得到类似"2.001Meg". 我应该能够像这样从 knumber 中获取浮点值(:val my-knumber),但通常打印机应该显示字符串,它也可以像这样访问(:string my-knumber)。这个数字将支持所有常用的 p、n、u、m、k、Meg、G 后缀,并在其中根据需要进行转换,例如(/ "1Meg" "1G") -> "1m"). 我希望能够将其传递给任何需要数字的函数。

无论如何,有人可以为此提出一个策略吗?我想我需要使用协议。我目前有一个(defrecord knumber [val string]),但我不确定下一步是什么。

clojure 数字满足哪些协议?我想我需要为此扩展一些现有的协议/接口。

谢谢

4

2 回答 2

4

我认为您的策略应该如下:

  • 将记录定义KNumber(defrecord knumber [value unit-map])
  • unit-map单位映射到整数指数(如果这些是工程数字,你会想要像 m/s^2 这样的单位,对吧?)。{"m" 1 "s" -2}它可能看起来像
  • KNumber实现java.lang.Number,以便您可以将它与 Clojure 中已经存在的其他数学函数一起使用。你需要实现doubleValuelongValue
  • 定义一个NumberWithUnits可以扩展到KNumbers 和普通 clojure 数字的协议。至少它应该有方法(numeric-value [number])(get-units [number])
  • 然后在你自己的命名空间中定义你的数学函数+,等等*,这些函数-对任何实现NumberWithUnits协议的东西进行操作并返回一个KNumber.
  • 关于不同的单位比例(例如“m”与“km”),我建议在单一比例上标准化每种单位类型的内部表示(例如“m”表示距离),但提供转换为其他单位比例的选项以用于输入/输出目的。
于 2012-08-05T03:14:12.343 回答
0

frinj是一个用于单位计算的 Clojure 库。查看源代码可能会给您一些好主意。

于 2012-08-07T12:07:37.657 回答