2012-08-04 8 views
6

Próbuję użyć protokołów, aby utworzyć typ numeru inżynieryjnego ("numer"), więc mogę powiedzieć, że (+ "1k" "2Meg") i uzyskać coś w rodzaju "2.001Meg". Powinienem być w stanie uzyskać wartość zmiennoprzecinkową z numeracji, tak jak (:val my-knumber), ale zwykle drukarka powinna wyświetlać ciąg znaków, który jest również dostępny tak, jak to jest (:string my-knumber). Ta liczba będzie obsługiwać wszystkie zwykłe przyrostki p, n, u, m, k, Meg, G i konwertować zgodnie z wymaganiami, na przykład (/ "1Meg" "1G") -> "1m"). Chcę móc przekazać to do dowolnej funkcji, która oczekuje liczby.Jak rozszerzyć protokoły numeryczne w Clojure

Czy ktoś może zaproponować strategię? Myślę, że muszę korzystać z protokołów. Obecnie mam (defrecord knumber [val string]), ale nie jestem pewien, co dalej.

Jakie protokoły spełniają numery clojure? Myślę, że muszę rozszerzyć niektóre istniejące protokoły/interfejsy do tego.

Dzięki

+0

Wiem, że to nie to samo, ale możesz użyć notacji naukowej: (/ 1e6 1e9) – DaoWen

Odpowiedz

4

Myślę, że strategia powinna chyba być następująca:

  • Definiowanie rekord KNumber jako coś jak (defrecord knumber [value unit-map])
  • Bądź unit-map mapie jednostek do Integer wykładniki (idziesz do chcesz jednostek takich jak m/s^2, jeśli są to liczby inżynieryjne, prawda?). Może to wyglądać jak {"m" 1 "s" -2},
  • Mieć implementować java.lang.Number, dzięki czemu można go używać z innymi funkcjami matematycznymi, które już istnieją w Clojure. Będziesz musiał wdrożyć doubleValue, itd.
  • Zdefiniuj protokół NumberWithUnits, który można rozszerzyć zarówno na KNumber s jak i normalne liczby clojure. Przynajmniej powinien mieć metody (numeric-value [number]) i (get-units [number])
  • Następnie zdefiniować funkcje matematyczne +, *, - itp we własnej przestrzeni nazw, które działają na coś, który implementuje protokół NumberWithUnits i zwracają KNumber.
  • Jeśli chodzi o różne skale jednostek (np. "M" w stosunku do "km"), sugerowałbym standaryzację w pojedynczej skali dla wewnętrznej reprezentacji dla każdego rodzaju jednostki (np. "M" dla odległości), ale zapewnienie opcji konwersji na inne wagi jednostek do celów wejścia/wyjścia.
0

frinj library to biblioteka Clojure do obliczeń z jednostkami. Zaglądanie do źródła prawdopodobnie da ci kilka fajnych pomysłów.