2012-08-04 53 views
6

我試圖使用協議來創建一個工程編號類型(「knumber」),所以我可以說(+ "1k" "2Meg")並得到類似"2.001Meg"的東西。我應該能夠從knumber中獲得浮點值,就像(:val my-knumber)一樣,但通常情況下,打印機應該顯示字符串,這也可以像(:string my-knumber)那樣訪問。這個數字將支持所有通常的p,n,u,m,k,Meg,G後綴,並根據需要進行轉換,如(/ "1Meg" "1G") -> "1m")。我希望能夠將此傳遞給任何需要數字的函數。如何在Clojure中擴展數字協議

無論如何,有人可以提出一個這樣的策略?我想我需要使用協議。我目前有一個(defrecord knumber [val string]),但我不確定接下來會發生什麼。

什麼協議clojure數字satsify?我想我需要爲此擴展一些現有的協議/接口。

感謝

+0

我知道這不是一回事,但你可以使用科學記數法:(/ 1e6 1e9) – DaoWen 2012-08-06 08:07:06

回答

4

我覺得你的策略也許應該是如下:

  • 定義記錄KNumber,就像這樣(defrecord knumber [value unit-map])
  • unit-map地圖的單位整數指數一(你要希望像m/s^2這樣的單位,如果這些是工程編號的話,對吧?)。它可能看起來像{"m" 1 "s" -2},
  • KNumber實施java.lang.Number,以便您可以將其與Clojure中已有的其他數學函數一起使用。您需要執行doubleValue,longValue
  • 定義一個協議NumberWithUnits,您可以擴展到KNumber s和普通clojure號碼。它至少應該有方法(numeric-value [number])(get-units [number])
  • 然後定義你的數學函數+*-等在自己的命名空間中的任何一個實現NumberWithUnits協議,並返回一個KNumber操作。
  • 關於不同的單位尺度(例如「m」與「km」),我建議在每個單位類型的內部表示上標準化(例如「m」表示距離),但提供轉換爲其他單位尺度的選項用於輸入/輸出目的。
0

frinj library是一個用於計算單位的Clojure庫。研究來源可能會給你一些不錯的想法。