を使用したアプローチを次に示しgen-class
ます。単位をチェックして正規化する関数をモックしただけです。実装されている唯一の操作は*
、 で使用される which ですforce
。
gen-class
コードは を使用しているため、次のコードをleiningen プロジェクト フォルダー のフォルダーにあるcompile
名前のファイルに保存してからロードする必要があることに注意してください。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)))