Hey together!
Im creating custom units with Unitful and am stumbling across a difficulty for which I havent yet found a solution for. I created a little module in which I am able to define new unitful dimensions and create custom units:
module MyUnits
using Unitful
export @u_str
function create_unit(name::String)
name = lowercase(name)
Dimension = uppercasefirst(name) * "Dimension" |> Meta.parse
DimensionQuote = uppercasefirst(name) * "Dimension"
dimension = name * "Dimension" |> Meta.parse
Unit = uppercasefirst(name) |> Meta.parse
UnitQuote = uppercasefirst(name)
unit = name |> Meta.parse
UNIT = uppercase(name) |> Meta.parse
return eval(
quote
@dimension $Dimension $DimensionQuote $dimension
@refunit $Unit $UnitQuote $unit $Dimension true
const $UNIT = Quantity{<:Real, $Dimension}
export $UNIT, $Unit, $unit, $dimension, $Dimension
end
)
end
create_unit("tomate")
create_unit("salad")
create_unit("euro")
function __init__()
Unitful.register(MyUnits)
end
end
This for now works fine. What I want to do with this is add units in form of vegetables like tomate, salad (later more), money like euro, and later many more very custom and unique dimesional units. In the create_unit function I am defining multiple “namings”, which are fed into the @dimension and @refunit macros to name and define the new unitful dimensions and units. Then I export some of the names so I can use it lateron outside the package. There are some case conventions I use here for the namings which are not very relevant for my problem, like uppercase, firstuppercase, no uppercase and so on.
If I load this module, I can use my newly created units like:
price(e::EURO, t::TOMATE) = e/t
price(5u"Euro", 2u"Tomate") # 2.5 Euro Tomate^-1
5u"Euro/Tomate" * 7u"Tomate" # 35 Euro
isa(5u"Euro/Tomate" * 7u"Tomate", EURO) # true
So until here everything is fine. What I now would like to do is the following. I want to “typecheck” my calculations in the form of:
tom::TOMATE = 7u"Tomate"
cost::EURO = 3u"Euro"
tomatoprice::WHATTYPE = cost / tom
I want to define calculations and type check them by putting ::TYPE next to the resulting variable. This is just a basic example, lateron there will be many combined types flying around, which is actually my initial motivation to implement this kind of “typechecking” with Unitful.
So, what do I have to put into the missing space at WHATTYPE? Of course there shall be something like EURO/TOMATO, but how does it get created automatically, or how can I access it if already existing? I know that there is the Quantity type in Unitful, but I havent yet understood it very well and how to use it for this purpose.
Thanks very much for help here! I am enjoying Unitful, but am still at the beginning of my learning. If you have some critics on my module and code structures above, please let me know aswell. Im still somehow new to Julia too.