aboutsummaryrefslogtreecommitdiff
path: root/stdlib/source/library/lux/type/unit/scale.lux
blob: efca489a0293b85433fe3ceb96522f3e39c5db9a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
(.using
 [library
  [lux (.except type)
   [control
    [parser
     ["<[0]>" code]]]
   ["[0]" macro (.only)
    [syntax (.only syntax)]]
   [math
    [number
     ["i" int]
     ["[0]" ratio (.only Ratio)]]]]]
 ["[0]" // (.only)
  ["/[1]" //]])

(type: .public (Scale s)
  (Interface
   (is (All (_ u) (-> (//.Qty Any u) (//.Qty s u)))
       up)
   (is (All (_ u) (-> (//.Qty s u) (//.Qty Any u)))
       down)
   (is Ratio
       ratio)))

(def .public (scale ratio)
  (Ex (_ s) (-> Ratio (Scale s)))
  (let [(open "/[0]") ratio]
    (implementation
     (def up
       (|>> //.number
            (i.* (.int /#numerator))
            (i./ (.int /#denominator))
            //.quantity))
     (def down
       (|>> //.number
            (i.* (.int /#denominator))
            (i./ (.int /#numerator))
            //.quantity))
     (def ratio
       ratio))))

(def .public (re_scaled from to quantity)
  (All (_ si so u) (-> (Scale si) (Scale so) (//.Qty si u) (//.Qty so u)))
  (let [(open "/[0]") (ratio./ (at from ratio)
                               (at to ratio))]
    (|> quantity
        //.number
        (i.* (.int /#numerator))
        (i./ (.int /#denominator))
        //.quantity)))

(def .public type
  (syntax (_ [it <code>.any])
    (macro.with_symbols [g!a]
      (in (list (` ((~! ///.by_example) [(~ g!a)]
                    (is (..Scale (~ g!a))
                        (~ it))
                    (~ g!a))))))))

(with_template [<order_of_magnitude> <up> <up_type> <down> <down_type>]
  [(def .public <up>
     (scale [ratio.#numerator <order_of_magnitude>
             ratio.#denominator 1]))
   
   (type: .public <up_type>
     (~ (..type <up>)))
   
   (def .public <down>
     (scale [ratio.#numerator 1
             ratio.#denominator <order_of_magnitude>]))
   
   (type: .public <down_type>
     (~ (..type <down>)))]

  [        1,000 kilo Kilo milli Milli]
  [    1,000,000 mega Mega micro Micro]
  [1,000,000,000 giga Giga nano  Nano ]
  )