如何在Clojure中扩展数值协议

时间:2012-08-04 19:05:57

标签: clojure protocols

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

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

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

由于

2 个答案:

答案 0 :(得分:4)

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

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

答案 1 :(得分:0)

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