How To Properly Use Unitful

I ran into the same issue. Below I describe how I inverstigated the problem and fixed the type definition (spoiler: solution is at the end).

julia> using Unitful

julia> a = typeof(1.0u"m")
Quantity{Float64, š‹, Unitful.FreeUnits{(m,), š‹, nothing}}

OK so let us define type b (a supposed alias for type a) as (note that you need the Unitful. prefix unless you import symbols m and š‹, a bold L, from Unitful):

julia> b = Quantity{Float64, Unitful.š‹, Unitful.FreeUnits{(Unitful.m,), Unitful.š‹, nothing}}
Quantity{Float64, š‹, Unitful.FreeUnits{(m,), š‹, nothing}}

a and b are printed exactly the same however they are different as shown by:

julia> a == b
false

Exactly what was observed by @acdupont at the start of this discussion.

Since a and b are parametric types, let us find out which of their parameters is/are different by introspection:

julia> a.parameters .== b.parameters
3-element BitVector:
 1
 1
 0

So the culprit is the 3rd one, a Unitful.FreeUnits structure, we use the same trick as above to compare its parameters:

julia> a.parameters[3].parameters .== b.parameters[3].parameters
3-element BitVector:
 0
 1
 1

So, the 1st parameter is now the one which is different. However:

julia> a.parameters[3].parameters[1]
(m,)

julia> b.parameters[3].parameters[1]
(m,)

which (wrongly) seems to indicate that both are 1-tuple with single element m. Let us check the type of the element:

julia> typeof(a.parameters[3].parameters[1][1])
Unitful.Unit{:Meter, š‹}

julia> typeof(b.parameters[3].parameters[1][1])
Unitful.FreeUnits{(m,), š‹, nothing}

Hooray, we finally found a difference!

Unrolling all this, the correct definition for b is:

julia> b = Quantity{Float64, Unitful.š‹, Unitful.FreeUnits{(Unitful.Unit{:Meter,Unitful.š‹}(0,1//1),), Unitful.š‹, nothing}}
Quantity{Float64, š‹, Unitful.FreeUnits{(m,), š‹, nothing}}

Let us check this:

julia> a == b
true

julia> a === b
true

To give a practical example that can be used to define precisely the type of a field in a structure (the original need), we can define the following type alias:

const Meters{T<:Real} = Quantity{T, Unitful.š‹, Unitful.FreeUnits{(Unitful.Unit{:Meter,Unitful.š‹}(0,1//1),), Unitful.š‹, nothing}}

and check that:

julia> typeof(1.0u"m") === Meters{Float64}
true

julia> typeof(1u"m") === Meters{Int}
true

julia> convert(Meters{Float32}, 2.3u"mm")
0.0023f0 m
7 Likes