# Changing the basic type of a Unitful quantity

**URL:** <https://discourse.julialang.org/t/changing-the-basic-type-of-a-unitful-quantity/119665>\
**Category:** General Usage\
**Tags:** unitful\
**Created:** [September 21, 2024, 7:23am UTC](https://discourse.julialang.org/t/changing-the-basic-type-of-a-unitful-quantity/119665 "2024-09-21T07:23:19Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![Maurizio\_Tomasi](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/maurizio_tomasi/32/384_2.png) [@Maurizio\_Tomasi](https://discourse.julialang.org/u/Maurizio_Tomasi)\
**Post date:** [September 21, 2024, 7:23am UTC](https://discourse.julialang.org/t/changing-the-basic-type-of-a-unitful-quantity/119665/1 "2024-09-21T07:23:19Z")

</div>

I’m developing some electromagnetic code and want to use Unitful.jl thoroughly to make sure that data structures and algorithms are physically consistent.

One feature I would like to have is the ability to quickly set up structures using a basic floating-point data type with the appropriate bitsize, e.g., `Float32` vs `Float64`. However, I struggle to understand how to make the Julia type system to do what I want.

I can explain the problem using a very simple 2D vector data structure as an example:

```julia
import Unitful: Length, m

struct Vec{T, L <: Length{T}}
    x::L
    y::L
end

```

This type works well with both `Float32` and `Float64` numbers:

```julia
julia> Vec(1.0m, 2.0m)
Vec{Float64, Quantity{Float64, 𝐋, Unitful.FreeUnits{(m,), 𝐋, nothing}}}(1.0 m, 2.0 m)
julia> Vec(1.0f0m, 2.0f0m)
Vec{Float32, Quantity{Float32, 𝐋, Unitful.FreeUnits{(m,), 𝐋, nothing}}}(1.0f0 m, 2.0f0 m)

```

Suppose that now I want to define an outer constructor where I pass the `Float32`/`Float64`/`ComplexF32`/… type explicitly, making sure that the constructor properly converts the types. This could be useful if e.g. I want to be sure to use a wide data type in some accuracy-sensitive algorithm.

In this particular example, I would like to write `Vec{Float64}(x, y)` and keep the lengths `x` and `y` stored as `Float64` lengths even if the values passed as `x` and `y` are `Float32`.

I struggle to understand how to code it, as the following attempt does not work:

```julia
julia> Vec{T}(x::L, y::L) where {T, L <: Length} = Vec{T, L}(T(x), T(y))

julia> Vec{Float64}(1.0f0m, 2.0f0m)
ERROR: TypeError: in Vec, in L, expected L<:(Union{Quantity{Float64, 𝐋, U}, Unitful.Level{L, S, Quantity{Float64, 𝐋, U}} where {L, S}} where U), got Type{Quantity{Float32, 𝐋, Unitful.FreeUnits{(m,), 𝐋, nothing}}}
Stacktrace:
 [1] (Vec{…} where L<:(Union{…} where U))(x::Quantity{…}, y::Quantity{…})
   @ Main ./REPL[10]:1
 [2] top-level scope
   @ REPL[15]:1
Some type information was truncated. Use `show(err)` to see complete types.

```

I understand that the problem lies in the fact that when I write `Vec{T, L}`, the type `L` is still based on `Float32`. But I fail to see an easy way to “promote” type `L` so that it keeps using the same measurement units (`m`, `ft`, `inch`…) as the input parameters while switching the basic type from `Float32` to `Float64`.

Can anybody provide me a few hints, please?

**Edit** : Fix a typo.

---

<div class="post-metadata">

**Author:** ![aryavorskiy](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/aryavorskiy/32/43466_2.png) [@aryavorskiy](https://discourse.julialang.org/u/aryavorskiy)\
**Post date:** [September 21, 2024, 10:30am UTC](https://discourse.julialang.org/t/changing-the-basic-type-of-a-unitful-quantity/119665/2 "2024-09-21T10:30:51Z")

</div>

Hi!

It seems that `convert(Quantity{T}, x)` instead of `T(x)` does what you need.

---

<div class="post-metadata">

**Author:** ![Maurizio\_Tomasi](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/maurizio_tomasi/32/384_2.png) [@Maurizio\_Tomasi](https://discourse.julialang.org/u/Maurizio_Tomasi)\
**Post date:** [September 22, 2024, 10:26am UTC](https://discourse.julialang.org/t/changing-the-basic-type-of-a-unitful-quantity/119665/3 "2024-09-22T10:26:34Z")

</div>

Fantastic! With this implementation

```julia
function Vec{T}(x::L, y::L) where {T, L <: Length}
    newx = convert(Quantity{T}, x)
    newy = convert(Quantity{T}, y)
    return Vec{T, typeof(newx)}(newx, newy)
end

```

this works as expected:

```julia
julia> Vec{Float64}(1.0f0m, 2.0f0m)
Vec{Float64, Quantity{Float64, 𝐋, Unitful.FreeUnits{(m,), 𝐋, nothing}}}(1.0 m, 2.0 m)

```

Thank you very much!
