# Dispatch on specific Unitful unit

**URL:** <https://discourse.julialang.org/t/dispatch-on-specific-unitful-unit/124774>\
**Category:** General Usage\
**Tags:** unitful\
**Created:** [January 14, 2025, 7:45pm UTC](https://discourse.julialang.org/t/dispatch-on-specific-unitful-unit/124774 "2025-01-14T19:45:54Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![Nathan\_Boyer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nathan_boyer/32/14825_2.png) [@Nathan\_Boyer](https://discourse.julialang.org/u/Nathan_Boyer)\
**Post date:** [January 14, 2025, 7:45pm UTC](https://discourse.julialang.org/t/dispatch-on-specific-unitful-unit/124774/1 "2025-01-14T19:45:54Z")

</div>

Continuing the discussion from [Unitful dispatch](https://discourse.julialang.org/t/unitful-dispatch/49480/9):

I want to dispatch specifically on `u"inch"`. What am I missing?  
In this MWE, I want `mm(1)`, `mm(1u"inch")`, and `mm(1.0u"inch")` to all return `25.4 mm`.

```julia
using Unitful
InchType = Quantity{
    <:Any,
    Unitful.𝐋,
    Unitful.FreeUnits{(Unitful.inch,), Unitful.𝐋, nothing},
}
function mm(x::Real)
    x * u"inch" |> u"mm" |> float
end
function mm(x::InchType)
    x |> u"mm" |> float
end

```

```julia-repl
julia> x = 1u"inch"
1 inch

julia> XType = typeof(x)
Quantity{Int64, 𝐋 , Unitful.FreeUnits{(inch,), 𝐋 , nothing}}

julia> InchType
Quantity{<:Any, 𝐋 , Unitful.FreeUnits{(inch,), 𝐋 , nothing}}

julia> XType <: InchType
false

julia> mm(x)
ERROR: MethodError: no method matching mm(::Quantity{Int64, 𝐋, Unitful.FreeUnits{(inch,), 𝐋,
 nothing}})
The function `mm` exists, but no method is defined for this combination of argument types.

Closest candidates are:
  mm(::Quantity{<:Any, 𝐋, Unitful.FreeUnits{(inch,), 𝐋, nothing}} , ::Quantity{<:Any, 𝐋, Uni
tful.FreeUnits{(inch,), 𝐋, nothing}} )
   @ Main C:\Users\nboyer.AIP\.julia\config\startup.jl:67
  mm(::Real, ::Real)
   @ Main C:\Users\nboyer.AIP\.julia\config\startup.jl:64
  mm(::Tuple{Quantity{<:Any, 𝐋, Unitful.FreeUnits{(inch,), 𝐋, nothing}}, Quantity{<:Any, 𝐋,
 Unitful.FreeUnits{(inch,), 𝐋, nothing}}} )
   @ Main C:\Users\nboyer.AIP\.julia\config\startup.jl:61
  ...

Stacktrace:
 [1] top-level scope
   @ REPL[1]:1

```

---

<div class="post-metadata">

**Author:** ![bcon](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bcon/32/23495_2.png) [@bcon](https://discourse.julialang.org/u/bcon)\
**Post date:** [January 14, 2025, 8:28pm UTC](https://discourse.julialang.org/t/dispatch-on-specific-unitful-unit/124774/2 "2025-01-14T20:28:12Z")

</div>

I’ve had this desire in the past but can’t find my resolution; since then I wrote [UnitTypes](https://github.com/mechanomy/UnitTypes.jl) to help with this sort of thing. The package works by providing macros that allow defining of new unit types and conversions between them. A parallel package, ExchangeUnitful, can provide converts to/from Unitful.  
N.B: I’m rewriting the macros to make the expression more natural.

---

<div class="post-metadata">

**Author:** ![juliohm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/juliohm/32/215266_2.png) [@juliohm](https://discourse.julialang.org/u/juliohm)\
**Post date:** [January 14, 2025, 8:45pm UTC](https://discourse.julialang.org/t/dispatch-on-specific-unitful-unit/124774/3 "2025-01-14T20:45:49Z")

</div>

One possible solution:

```julia
using Unitful

# type to dispatch on length quantities
const Length{T} = Quantity{T,u"𝐋"}

# requested behavior
mm(x::Number) = mm(x * u"inch")
mm(x::Length) = float(uconvert(u"mm", x))
mm(x::Quantity) = throw(ArgumentError("invalid units"))

# examples of usage
mm(1) # 25.4 mm
mm(1u"inch") # 25.4 mm
mm(1u"hr") # invalid units
```

---

<div class="post-metadata">

**Author:** ![Nathan\_Boyer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nathan_boyer/32/14825_2.png) [@Nathan\_Boyer](https://discourse.julialang.org/u/Nathan_Boyer)\
**Post date:** [January 14, 2025, 9:00pm UTC](https://discourse.julialang.org/t/dispatch-on-specific-unitful-unit/124774/4 "2025-01-14T21:00:34Z")

</div>

I’m mostly just confused why

```julia-repl
julia> x = 1u"inch"
1 inch

julia> XType = typeof(x)
Quantity{Int64, 𝐋, Unitful.FreeUnits{(inch,), 𝐋, nothing}}

julia> LengthType = Quantity{<:Any, Unitful.𝐋}
Quantity{<:Any, 𝐋}

julia> XType <: LengthType
true

```

but

```julia-repl
julia> InchType = Quantity{
           <:Any,
           Unitful.𝐋,
           Unitful.FreeUnits{(Unitful.inch,), Unitful.𝐋, nothing},
       }
Quantity{<:Any, 𝐋, Unitful.FreeUnits{(inch,), 𝐋, nothing}}

julia> XType <: InchType
false

```

when I’ve copied everything else exactly.

---

<div class="post-metadata">

**Author:** ![juliohm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/juliohm/32/215266_2.png) [@juliohm](https://discourse.julialang.org/u/juliohm)\
**Post date:** [January 14, 2025, 9:14pm UTC](https://discourse.julialang.org/t/dispatch-on-specific-unitful-unit/124774/5 "2025-01-14T21:14:01Z")

</div>

> [@Nathan\_Boyer](#):
>
> when I’ve copied everything else exactly.

Julia’s type parameters are invariant:

> **[Types · The Julia Language](https://docs.julialang.org/en/v1/manual/types/#man-parametric-composite-types)**
>
> Documentation for The Julia Language.

Another example:

```julia
julia> abstract type A{T₁,T₂,T₃} end

julia> A{Int,Int,Int} <: A{Int,Int} <: A{Int} <: A
true

julia> A{Int,Int,Int} <: A{Number,Number,Number}
false

```

---

<div class="post-metadata">

**Author:** ![lxvm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lxvm/32/50010_2.png) [@lxvm](https://discourse.julialang.org/u/lxvm)\
**Post date:** [January 15, 2025, 12:43am UTC](https://discourse.julialang.org/t/dispatch-on-specific-unitful-unit/124774/6 "2025-01-15T00:43:49Z")

</div>

I found this confusing but it turns out to be due to how Unitful.jl prints units and what you really want is the type of a unit, demonstrated below:

```jl
julia> InchType = Quantity{
           <:Any,
           Unitful.𝐋,
           typeof(Unitful.inch),
       }
Quantity{<:Any, 𝐋, Unitful.FreeUnits{(inch,), 𝐋, nothing}}

julia> XType <: InchType
true

```

---

<div class="post-metadata">

**Author:** ![lxvm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lxvm/32/50010_2.png) [@lxvm](https://discourse.julialang.org/u/lxvm)\
**Post date:** [January 15, 2025, 1:04am UTC](https://discourse.julialang.org/t/dispatch-on-specific-unitful-unit/124774/7 "2025-01-15T01:04:12Z")

</div>

However, if you want to dispatch on the unit, it could also be more readable to treat the unit like a trait:

```jl
f(x::Number) = _f(unit(x), x)
_f(::Unitful.Units, x) = nothing
_f(::typeof(Unitful.inch), x) = something

```

---

<div class="post-metadata">

**Author:** ![Nathan\_Boyer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nathan_boyer/32/14825_2.png) [@Nathan\_Boyer](https://discourse.julialang.org/u/Nathan_Boyer)\
**Post date:** [July 11, 2025, 1:32pm UTC](https://discourse.julialang.org/t/dispatch-on-specific-unitful-unit/124774/8 "2025-07-11T13:32:11Z")

</div>

Saving this here for myself:

> [@Julia's type system : what am I missing?](https://discourse.julialang.org/t/julias-type-system-what-am-i-missing/130618/12):
>
> Adding to @Daniel_Berge 's answer, you can easily dispatch on more specific aliases: const Len{T} = Quantity{T,u"𝐋"} const Met{T} = Quantity{T,u"𝐋",typeof(m)} const Deg{T} = Quantity{T,NoDims,typeof(°)} const Rad{T} = Quantity{T,NoDims,typeof(rad)} You don’t need to construct concrete Unitful.jl types for dispatch. And you can let Julia figure out the exact type in a field using a type parameter: struct Foo{L\<:Met} len::L end
