I’m trying to use protocols to create an engineering number type (a “knumber”), so I can say (+ "1k" "2Meg") and get something like "2.001Meg". I should be able to get the floating point value from the knumber like so (:val my-knumber), but normally the printer should display the string, which is also accessible like so (:string my-knumber). This number will support all the usual p, n, u, m, k, Meg, G suffixes, and convert as required among them, such as (/ "1Meg" "1G") -> "1m"). I want to be able to pass this to any function which expects a number.
Anyway, Can someone suggest a strategy for this? I think I need to use protocols. I currently have a (defrecord knumber [val string]) but I’m not sure what’s next.
What protocols do clojure numbers satsify? I’m thinking I need to extend some existing protocols/interfaces for this.
Thanks
I think your strategy should probably be as follows:
KNumberas something like(defrecord knumber [value unit-map])unit-mapa map of units to integer exponents (you are going to want units like m/s^2 if these are engineering numbers, right?). It might look something like{"m" 1 "s" -2},KNumberimplementjava.lang.Numberso that you can use it with other mathematical functions that already exist in Clojure. You’ll need to implementdoubleValue,longValueetc.NumberWithUnitsthat you can extend to bothKNumbers and normal clojure numbers. At a minimum it should have methods(numeric-value [number])and(get-units [number])+,*,-etc. in your own namespace that operate on anything that implements theNumberWithUnitsprotocol and return aKNumber.