2012-08-04 12 views
6

Ich versuche, Protokolle zu verwenden, um eine technische Nummer Typ (ein "knumber") zu erstellen, so kann ich (+ "1k" "2Meg") sagen und etwas wie "2.001Meg" bekommen. Ich sollte in der Lage sein, den Gleitkommawert wie (:val my-knumber) aus dem Knubber zu bekommen, aber normalerweise sollte der Drucker die Zeichenkette anzeigen, die auch so zugänglich ist (:string my-knumber). Diese Nummer unterstützt alle üblichen Suffixe für p, n, u, m, k, Meg und G und kann nach Bedarf konvertiert werden, z. B. (/ "1Meg" "1G") -> "1m"). Ich möchte das an jede Funktion weitergeben können, die eine Nummer erwartet.Wie zu erweitern numerische Protokolle in Clojure

Wie auch immer, kann jemand eine Strategie dafür vorschlagen? Ich denke, ich muss Protokolle verwenden. Ich habe derzeit eine (defrecord knumber [val string]), aber ich bin mir nicht sicher, was als nächstes kommt.

Mit welchen Protokollen werden die Clojure-Nummern verknüpft? Ich denke, dass ich einige vorhandene Protokolle/Schnittstellen dafür erweitern muss.

Dank

+0

Ich weiß, es ist nicht das Gleiche, aber Sie können einfach wissenschaftliche Notation verwenden: (/ 1e6 1e9) – DaoWen

Antwort

4

Ich denke, Ihre Strategie wahrscheinlich wie folgt sein sollte:

  • KNumber als etwas den Datensatz definieren wie (defrecord knumber [value unit-map])
  • unit-map Erstellen Sie eine Karte von Einheiten Exponenten auf Integer (Sie gehen zu wollen Einheiten wie m/s^2, wenn das sind Engineering-Zahlen, nicht wahr?). Es könnte in etwa so aussehen: {"m" 1 "s" -2},
  • Haben KNumber implementieren java.lang.Number, so dass Sie es mit anderen mathematischen Funktionen verwenden können, die bereits in Clojure vorhanden sind. Sie müssen doubleValue, longValue usw. implementieren.
  • Definieren Sie ein Protokoll NumberWithUnits, das Sie sowohl auf KNumber s als auch auf normale Clojure-Nummern erweitern können. Zumindest sollte es Methoden (numeric-value [number]) und (get-units [number])
  • Dann + Ihre mathematischen Funktionen definieren, *, - usw. in Ihrem eigenen Namensraum, der auf irgendetwas arbeiten, das das NumberWithUnits-Protokoll implementiert und gibt ein KNumber.
  • In Bezug auf verschiedene Einheitenskalen (zB "m" vs. "km") würde ich vorschlagen, auf einer einzigen Skala für die interne Darstellung für jeden Einheitentyp zu standardisieren (zB "m" für Entfernungen), aber Optionen für die Umwandlung in andere Einheitenskalen bereitzustellen für Eingabe-/Ausgabezwecke.
0

Die frinj library Clojure ist eine Bibliothek für Berechnungen mit Einheiten. Wenn Sie sich die Quelle ansehen, werden Sie wahrscheinlich einige nette Ideen bekommen.

Verwandte Themen