*{m1, m2, s1, s2, kg1, kg2}(x::SI{m1, s1, kg1}, y::SI{m2, s2, kg2}) = SI{m1 + m2, s1 + s2, kg1 + kg2}(x.value * y.value)
*{m, s, kg}(x::Number, y::SI{m, s, kg}) = SI{m, s, kg}(x * y.value)
*{m, s, kg}(x::SI{m, s, kg}, y::Number) = SI{m, s, kg}(x.value * y)
^{m, s, kg}(x::SI{m, s, kg}, n::Int) = SI{n * m, n * s, n * kg}(x.value^n)
/{m1, m2, s1, s2, kg1, kg2}(x::SI{m1, s1, kg1}, y::SI{m2, s2, kg2}) = SI{m1 - m2, s1 - s2, kg1 - kg2}(x.value / y.value)
/{m, s, kg}(x::Number, y::SI{m, s, kg}) = SI{-m, -s, -kg}(x / y.value)
/{m, s, kg}(x::SI{m, s, kg}, y::Number) = SI{m, s, kg}(x.value / y)
+{m, s, kg}(x::SI{m, s, kg}, y::SI{m, s, kg}) = SI{m, s, kg}(x.value + y.value)
+{m1, m2, s1, s2, kg1, kg2}(x::SI{m1, s1, kg1}, y::SI{m2, s2, kg2}) = throw("addition of incompatible units")
-{m, s, kg}(x::SI{m, s, kg}, y::SI{m, s, kg}) = SI{m, s, kg}(x.value - y.value)
-{m1, m2, s1, s2, kg1, kg2}(x::SI{m1, s1, kg1}, y::SI{m2, s2, kg2}) = throw("subtraction of incompatible units")
typealias Meter SI{ 1, 0, 0}
typealias Second SI{ 0, 1, 0}
typealias Kilogram SI{ 0, 0, 1}
typealias Hertz SI{ 0, -1, 0}
typealias Newton SI{ 1, -2, 1}
typealias Pascal SI{-1, -2, 1}
typealias Joule SI{ 2, -2, 1}
typealias Watt SI{ 2, -3, 1}
m = Meter(1.0)
s = Second(1.0)
kg = Kilogram(1.0)
Hz = Hertz(1.0)
N = Newton(1.0)
Pa = Pascal(1.0)
J = Joule(1.0)
W = Watt(1.0)
show(io, x::Meter) = print(io, "$(x.value) m")
show(io, x::Second) = print(io, "$(x.value) s")
show(io, x::Kilogram) = print(io, "$(x.value) kg")
show(io, x::Hertz) = print(io, "$(x.value) Hz")
show(io, x::Newton) = print(io, "$(x.value) N")
show(io, x::Pascal) = print(io, "$(x.value) Pa")
show(io, x::Joule) = print(io, "$(x.value) J")
show(io, x::Watt) = print(io, "$(x.value) W")
function unit_string(s, n)
if n == 0
return ""
elseif n == 1
return s
else
return "$s^$n"
end
end
function show{m, s, kg}(io, x::SI{m, s, kg})
units = [unit_string("m", m), unit_string("s", s), unit_string("kg", kg)]
units = filter(str -> str != "", units)
print(io, "$(x.value) " * join(units, "⋅"))
end
With this you can do things like
julia> 5kg*3s*7m^2
105.0 m^2⋅s⋅kg
julia> 70kg*9.81m/s^2
686.7 N
However, dispatch on negative integer parameters doesn't seem to work properly at the moment.
julia> 70kg*(9.81m/s^2)
no method *(SI{0,0,1},SI{1,-2,0})
in method_missing at base.jl:70
--