【问题标题】:How to extend numerical protocols in Clojure如何在 Clojure 中扩展数值协议
【发布时间】:2012-08-02 10:04:50
【问题描述】:

我正在尝试使用协议来创建工程编号类型(“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 数字满足哪些协议?我想我需要为此扩展一些现有的协议/接口。

谢谢

【问题讨论】:

  • 我知道这不是一回事,但你可以使用科学计数法:(/1e6 1e9)

标签: clojure protocols


【解决方案1】:

frinj library 是一个用于单位计算的 Clojure 库。查看源代码可能会给您一些不错的想法。

【讨论】:

    【解决方案2】:

    我觉得你的策略大概应该是这样的:

    • 将记录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”表示距离),但提供转换为其他单位比例的选项用于输入/输出目的。

    【讨论】:

    • 你如何“让KNumber实现java.lang.Number”? defprotocol只支持实现接口,java的Number是一个抽象类。
    猜你喜欢
    • 2011-12-21
    • 1970-01-01
    • 1970-01-01
    • 2021-03-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多