我想在Clojure中实现一些基本的物理/化学公式。我不想强调性能,而是强调便利性,因此主要功能是类型检查。我当时认为将meta附加到数字上可以完成任务。
例如,此功能:
(defn force [mass accel]
(* mass accel))
应该
我可以*
在名称空间中适当地重载和其他功能。
唯一的问题是不可能将meta附加到Double
。获得类似数字但可以包含元数据的东西的好方法是什么?
这是使用的方法gen-class
。我只是嘲笑了检查和归一化单元的功能。实现的唯一操作是*
在中使用的操作force
。
请注意,由于该代码正在使用gen-class
,因此compile
您需要将以下代码保存到leiningen项目文件夹big_decimal_meta.clj
的src
文件夹中命名的文件中,然后进行加载。
BigDecimalMeta
使用gen-class
:
(ns big-decimal-meta
(:refer-clojure :exclude [* force])
(:gen-class
:name BigDecimalMeta
:extends java.math.BigDecimal
:state metadata
:init init
:implements [clojure.lang.IObj]))
(defn -init [& args]
[args (atom nil)])
(defn -withMeta [this metadata]
(reset! (.metadata this) metadata)
this)
(defn -meta [this]
(deref (.metadata this)))
(compile 'big-decimal-meta)
*
并force
通过一些示例代码起作用:
(def x (with-meta (BigDecimalMeta. 1) {:unit :kg}))
(def y (with-meta (BigDecimalMeta. 3.5) {:unit :mss}))
(def z (with-meta (BigDecimalMeta. 4.5) {:unit :V}))
(defn unit [x]
(-> x meta :unit))
(defn * [x y]
(BigDecimalMeta. (str (.multiply x y))))
(defn mass? [x]
(#{:kg :gr :mg ,,,} (unit x)))
(defn accel? [x]
(#{:mss ,,,} (unit x)))
(defn to-kg [x] x)
(defn to-mss [x] x)
(defn force [mass accel]
(assert (mass? mass))
(assert (accel? accel))
(let [mass (to-kg mass)
accel (to-mss accel)]
(with-meta (* mass accel) {:unit :N})))
(println (force x y) (meta (force x y)))
(println (force x z) (meta (force x z)))
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句