How to extend numerical protocols in Clojure

I try to use protocols to create an engineering number type ("knumber"), so I can say (+ "1k" "2Meg") and get something like "2.001Meg" . I would have to get the floating point value from the dense type (:val my-knumber) , but usually the printer should display a string that is also available like this (:string my-knumber) . This number will support all regular p, n, u, m, k, Meg, G suffixes and convert them as needed, for example (/ "1Meg" "1G") -> "1m") . I want to pass this to any function that expects a number.

Anyway, can anyone suggest a strategy for this? I think I need to use protocols. I currently have (defrecord knumber [val string]) , but I'm not sure what next.

What protocols have clojure satsify numbers? I think I need to extend some existing protocols / interfaces for this.

thanks

+6
source share
2 answers

I think your strategy should be as follows:

  • Define the KNumber entry as something like (defrecord knumber [value unit-map])
  • Make a unit-map map of units with integer metrics (you need units like m / s ^ 2 if it's engineering numbers, right?). It might look something like {"m" 1 "s" -2} ,
  • Have KNumber implement java.lang.Number so you can use it with other math functions that already exist in Clojure. You will need to implement doubleValue , longValue , etc.
  • Define the NumberWithUnits protocol, which can be extended to KNumber and normal clojure numbers. At a minimum, it should have (numeric-value [number]) and (get-units [number]) methods
  • Then define your math functions + , * , - , etc. in your own namespace that runs on anything that implements the NumberWithUnits protocol and returns KNumber .
  • Regarding different units of measure (for example, β€œm” and β€œkm”), I would suggest standardizing a single scale for the internal representation for each type of unit (for example, β€œm” for distances), but providing options for converting to other units of measurement for input / output goals.
+4
source

The frinj library is a Clojure library for unit calculations. A glance at the source will probably give you some nice ideas.

0
source

Source: https://habr.com/ru/post/922128/


All Articles