如何在Clojure中扩展数字协议

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

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

不管怎样,有人能提出一个策略吗?我想我需要使用协议。我目前有一个
(defrecord knumber[val string])
,但我不确定下一步是什么

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


谢谢

我想你的策略应该是:

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

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

我知道这不是一回事,但您可以使用科学符号:(/1e6 1e9)您如何“拥有
KNumber
实现
java.lang.Number
defprotocol
只支持实现接口,java的
Number
是一个抽象类。