| 1 | package metascala |
|---|
| 2 | |
|---|
| 3 | object Units { |
|---|
| 4 | import Integers._ |
|---|
| 5 | import Utils._ |
|---|
| 6 | import Addables._ |
|---|
| 7 | import Subtractables._ |
|---|
| 8 | |
|---|
| 9 | trait Unit { |
|---|
| 10 | type M <: MInt |
|---|
| 11 | type KG <: MInt |
|---|
| 12 | type S <: MInt |
|---|
| 13 | type A <: MInt |
|---|
| 14 | type K <: MInt |
|---|
| 15 | type Mol <: MInt |
|---|
| 16 | type CD <: MInt |
|---|
| 17 | } |
|---|
| 18 | |
|---|
| 19 | final class TUnit[_M <: MInt, _KG <: MInt, _S <: MInt, _A <: MInt, _K <: MInt, _Mol <: MInt, _CD <: MInt] { |
|---|
| 20 | type M = _M |
|---|
| 21 | type KG = _KG |
|---|
| 22 | type S = _S |
|---|
| 23 | type A = _A |
|---|
| 24 | type K = _K |
|---|
| 25 | type Mol = _Mol |
|---|
| 26 | type CD = _CD |
|---|
| 27 | } |
|---|
| 28 | |
|---|
| 29 | case class Quantity[M <: MInt, KG <: MInt, S <: MInt, A <: MInt, K <: MInt, Mol <: MInt, CD <: MInt](value : Double) { |
|---|
| 30 | type This = Quantity[M, KG, S, A, K, Mol, CD] |
|---|
| 31 | def +(m : This) = Quantity[M, KG, S, A, K, Mol, CD](value + m.value) |
|---|
| 32 | def -(m : This) = Quantity[M, KG, S, A, K, Mol, CD](value - m.value) |
|---|
| 33 | |
|---|
| 34 | def *[M2 <: MInt, KG2 <: MInt, S2 <: MInt, A2 <: MInt, K2 <: MInt, Mol2 <: MInt, CD2 <: MInt]( |
|---|
| 35 | m : Quantity[M2, KG2, S2, A2, K2, Mol2, CD2]) = |
|---|
| 36 | Quantity[M + M2, KG + KG2, S + S2, A + A2, K + K2, Mol + Mol2, CD + CD2](value * m.value) |
|---|
| 37 | |
|---|
| 38 | def /[M2 <: MInt, KG2 <: MInt, S2 <: MInt, A2 <: MInt, K2 <: MInt, Mol2 <: MInt, CD2 <: MInt]( |
|---|
| 39 | m : Quantity[M2, KG2, S2, A2, K2, Mol2, CD2]) = |
|---|
| 40 | Quantity[M - M2, KG - KG2, S - S2, A - A2, K - K2, Mol - Mol2, CD - CD2](value / m.value) |
|---|
| 41 | |
|---|
| 42 | def apply(v : Double) = Quantity[M, KG, S, A, K, Mol, CD](v * value) |
|---|
| 43 | } |
|---|
| 44 | |
|---|
| 45 | implicit def measure(v : Double) = Quantity[_0, _0, _0, _0, _0, _0, _0](v) |
|---|
| 46 | |
|---|
| 47 | val m = Quantity[_1, _0, _0, _0, _0, _0, _0](1) |
|---|
| 48 | val kg = Quantity[_0, _1, _0, _0, _0, _0, _0](1) |
|---|
| 49 | val s = Quantity[_0, _0, _1, _0, _0, _0, _0](1) |
|---|
| 50 | val a = Quantity[_0, _0, _0, _1, _0, _0, _0](1) |
|---|
| 51 | val k = Quantity[_0, _0, _0, _0, _1, _0, _0](1) |
|---|
| 52 | val mol = Quantity[_0, _0, _0, _0, _0, _1, _0](1) |
|---|
| 53 | val cd = Quantity[_0, _0, _0, _0, _0, _0, _1](1) |
|---|
| 54 | |
|---|
| 55 | type Length = Quantity[_1, _0, _0, _0, _0, _0, _0] |
|---|
| 56 | type Mass = Quantity[_0, _1, _0, _0, _0, _0, _0] |
|---|
| 57 | type Time = Quantity[_0, _0, _1, _0, _0, _0, _0] |
|---|
| 58 | type Currency = Quantity[_0, _0, _0, _1, _0, _0, _0] |
|---|
| 59 | type Temperature = Quantity[_0, _0, _0, _0, _1, _0, _0] |
|---|
| 60 | type Mol = Quantity[_0, _0, _0, _0, _0, _1, _0] |
|---|
| 61 | type LuminousIntensity = Quantity[_0, _0, _0, _0, _0, _0, _1] |
|---|
| 62 | |
|---|
| 63 | type Area = Quantity[_2, _0, _0, _0, _0, _0, _0] |
|---|
| 64 | type Volume = Quantity[_3, _0, _0, _0, _0, _0, _0] |
|---|
| 65 | type Speed = Quantity[_1, _0, _1#Neg, _0, _0, _0, _0] |
|---|
| 66 | type Acceleration = Quantity[_1, _0, _2#Neg, _0, _0, _0, _0] |
|---|
| 67 | } |
|---|