2012-08-04 36 views
6

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

无论如何,有人可以提出一个这样的策略?我想我需要使用协议。我目前有一个(defrecord knumber [val string]),但我不确定接下来会发生什么。

什么协议clojure数字satsify?我想我需要为此扩展一些现有的协议/接口。

感谢

+0

我知道这不是一回事,但你可以使用科学记数法:(/ 1e6 1e9) – DaoWen 2012-08-06 08:07:06

回答

4

我觉得你的策略也许应该是如下:

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

frinj library是一个用于计算单位的Clojure库。研究来源可能会给你一些不错的想法。