aboutsummaryrefslogtreecommitdiff
path: root/stdlib/source/library/lux/meta/type/unit.lux
blob: 4aa27fbfda621cd7a44ba24f0f454bb7ebf0c690 (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
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
... https://en.wikipedia.org/wiki/Dimensional_analysis
(.require
 [library
  [lux (.except type)
   [abstract
    [equivalence (.only Equivalence)]
    [order (.only Order)]
    [enum (.only Enum)]]
   [math
    [number
     ["i" int]]]
   [meta
    ["[0]" code
     ["<[1]>" \\parser]]
    ["[0]" macro (.only)
     [syntax (.only syntax)]]]]]
 ["[0]" // (.only)
  ["[0]" primitive (.except def)]])

(primitive.def .public (Measure scale unit)
  Int

  (def .public measure
    (All (_ scale unit) (-> Int (Measure scale unit)))
    (|>> abstraction))

  (def .public number
    (All (_ scale unit) (-> (Measure scale unit) Int))
    (|>> representation))

  (def .public equivalence
    (All (_ scale unit) (Equivalence (Measure scale unit)))
    (implementation
     (def (= reference sample)
       (i.= (representation reference) (representation sample)))))

  (def .public order
    (All (_ scale unit) (Order (Measure scale unit)))
    (implementation
     (def equivalence ..equivalence)
     
     (def (< reference sample)
       (i.< (representation reference) (representation sample)))))

  (def .public enum
    (All (_ scale unit) (Enum (Measure scale unit)))
    (implementation
     (def order ..order)
     (def succ (|>> representation ++ abstraction))
     (def pred (|>> representation -- abstraction))))

  (with_template [<name> <op>]
    [(def .public (<name> param subject)
       (All (_ scale unit) (-> (Measure scale unit) (Measure scale unit) (Measure scale unit)))
       (abstraction (<op> (representation param)
                          (representation subject))))]

    [+ i.+]
    [- i.-]
    )

  (with_template [<name> <op> <p> <s> <p*s>]
    [(def .public (<name> param subject)
       (All (_ scale p s) (-> (Measure scale <p>) (Measure scale <s>) (Measure scale <p*s>)))
       (abstraction (<op> (representation param)
                          (representation subject))))]

    [* i.* p s [p s]]
    [/ i./ p [p s] s]
    )

  (.type .public (Unit a)
    (Interface
     (is (-> Int (Measure Any a))
         in)
     (is (-> (Measure Any a) Int)
         out)))

  (def .public (unit _)
    (Ex (_ a) (-> Any (Unit a)))
    (implementation
     (def in ..measure)
     (def out ..number)))
  )

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

(with_template [<unit> <type>]
  [(def .public <unit>
     (..unit []))
   
   (.def .public <type>
     (let [[module _] (symbol .._)
           [_ short] (symbol <type>)]
       {.#Named [module short]
                (..type <unit>)}))]

  [gram Gram]
  [meter Meter]
  [litre Litre]
  [second Second]
  )