2012-08-04 9 views
6

Estoy tratando de usar protocolos para crear un tipo de número de ingeniería (un "knumber"), así que puedo decir (+ "1k" "2Meg") y obtener algo así como "2.001Meg". Debería poder obtener el valor del punto flotante del knumber como (:val my-knumber), pero normalmente la impresora debería mostrar la cadena, que también es accesible como (:string my-knumber). Este número soportará todos los sufijos usuales p, n, u, m, k, Meg, G, y lo convertirá según se requiera entre ellos, como (/ "1Meg" "1G") -> "1m"). Quiero poder pasar esto a cualquier función que espera un número.Cómo extender los protocolos numéricos en Clojure

De todos modos, ¿alguien puede sugerir una estrategia para esto? Creo que necesito usar protocolos. Actualmente tengo un (defrecord knumber [val string]) pero no estoy seguro de lo que vendrá después.

¿Qué protocolos satsify números de cliché? Estoy pensando que necesito extender algunos protocolos/interfaces existentes para esto.

Gracias

+0

Sé que no es lo mismo, pero puede usar notación científica: (/ 1e6 1e9) – DaoWen

Respuesta

4

creo que su estrategia probablemente debería ser el siguiente:

  • definir el registro KNumber como algo parecido a (defrecord knumber [value unit-map])
  • Haga unit-map un mapa de unidades de exponentes enteros (que se va a quiere unidades como m/s^2 si se trata de números de ingeniería, ¿no?). Puede parecerse a {"m" 1 "s" -2},
  • Tener KNumber implementar java.lang.Number para que pueda usarlo con otras funciones matemáticas que ya existen en Clojure. Necesitará implementar doubleValue, longValue, etc.
  • Defina un protocolo NumberWithUnits que puede extender tanto a KNumber como a números normales de clojure. Como mínimo debe tener métodos (numeric-value [number]) y (get-units [number])
  • a continuación, definir sus funciones matemáticas +, *, etc. - en su propio espacio de nombres que operan en cualquier cosa que implementa el protocolo NumberWithUnits y devolver una KNumber.
  • En cuanto a diferentes escalas de unidades (por ejemplo, "m" vs. "km"), sugiero estandarizar en una escala única para la representación interna para cada tipo de unidad (por ejemplo, "m" para distancias) pero proporcionando opciones para la conversión para propósitos de entrada/salida.
0

El frinj library es una biblioteca Clojure para los cálculos con unidades. Mirar hacia la fuente probablemente le dará algunas buenas ideas.

Cuestiones relacionadas