# Type of array containing units from Unitful

**URL:** https://discourse.julialang.org/t/type-of-array-containing-units-from-unitful/103020
**Category:** General Usage
**Tags:** unitful
**Created:** [August 21, 2023, 8:30am UTC](https://discourse.julialang.org/t/type-of-array-containing-units-from-unitful/103020 "2023-08-21T08:30:03Z")
**Posts on this page:** 9
**Page:** 1

<div class="post-metadata">

### Author: ![Iddingsite](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/iddingsite/32/31840_2.png) [@Iddingsite](https://discourse.julialang.org/u/Iddingsite)
#### Post date: [August 21, 2023, 8:30am UTC](https://discourse.julialang.org/t/type-of-array-containing-units-from-unitful/103020/1 "2023-08-21T08:30:03Z")

</div>

Hello! I am struggling a bit with types coming from Unitful in arrays. Here is a simple MWE:

```julia
using Unitful

array_unit = [1.0, 3, 4]u"yr"

```

If I look at the type of array\_unit, I obtain this:

```julia
typeof(array_unit)

```

```julia
Vector{Quantity{Float64, 𝐓, FreeUnits{(yr,), 𝐓, nothing}}} (alias for Array{Quantity{Float64, 𝐓, Unitful.FreeUnits{(yr,), 𝐓, nothing}}, 1})

```

So why does this not work?

```julia
array_unit::Array{Quantity{Float64, Unitful.𝐓, Unitful.FreeUnits{(Unitful.yr,), Unitful.𝐓, nothing}}, 1}

```

This throws:

```julia
ERROR: TypeError: in typeassert, expected Vector{Quantity{Float64, 𝐓, Unitful.FreeUnits{(yr,), 𝐓, nothing}}}, got a value of type Vector{Quantity{Float64, 𝐓, Unitful.FreeUnits{(yr,), 𝐓, nothing}}}
Stacktrace:
 [1] top-level scope
   @ REPL[13]:1

```

which seems to be the same thing to me…

I am still a bit new to types so maybe I am missing something fondamental here.

Cheers,

---

<div class="post-metadata">

### Author: ![sostock](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sostock/32/5546_2.png) [@sostock](https://discourse.julialang.org/u/sostock)
#### Post date: [August 21, 2023, 9:09am UTC](https://discourse.julialang.org/t/type-of-array-containing-units-from-unitful/103020/2 "2023-08-21T09:09:23Z")

</div>

The following works:

```julia
array_unit::Array{Quantity{Float64, Unitful.𝐓, typeof(Unitful.yr)}, 1}

```

The problem is that `Unitful` customizes how some of its types are printed to make them shorter. So the type that is printed is not the actual type.

In this specific case, `Unitful.yr` is not the same object as the one represented by `yr` in `Unitful.FreeUnits{(yr,), 𝐓, nothing}`. You can see that if you look at the type of `Unitful.yr`:

```julia
julia> typeof(Unitful.yr)
Unitful.FreeUnits{(yr,), 𝐓, nothing}

```

`Unitful.yr` is already a `Unitful.FreeUnits` object, while the object that `yr` refers to in the above type signature is a `Unitful.Unit` object (specifically, it is the object `Unit{:Year, 𝐓}(0, 1//1)` with type `Unit{:Year, 𝐓}`).

I think the custom printing of `Unit` (making it look as if it were a `FreeUnits`) is really confusing and we should get rid of it, but the type signatures would be _a lot_ longer if we removed customized type printing. Maybe, since we already customize type printing, we should print `Quantity` types in the following way:

```julia
Quantity{Float64, 𝐓, typeof(yr)}

```

I think this would be an improvement to the printing of `Quantity` types, but doesn’t solve the problem of how `Units` types are displayed.

---

<div class="post-metadata">

### Author: ![Jollywatt](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jollywatt/32/202198_2.png) [@Jollywatt](https://discourse.julialang.org/u/Jollywatt)
#### Post date: [August 21, 2023, 12:27pm UTC](https://discourse.julialang.org/t/type-of-array-containing-units-from-unitful/103020/3 "2023-08-21T12:27:33Z")

</div>

Hmm… perhaps a way to improve pretty printing of `Unitful` types while also achieving copy-into-REPL-ability is to draw inspiration from `@NamedTuple` in Julia ≥v1.5.

Suppose `Unitful` exported a macro so that, for example,

```julia
@Quantity{Float64, 𝐓, yr} === Quantity{Float64, Unitful.𝐓, typeof(Unitful.yr)}

```

Then types could be pretty printed as calls to this macro.

I really like that idea.

---

<div class="post-metadata">

### Author: ![Iddingsite](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/iddingsite/32/31840_2.png) [@Iddingsite](https://discourse.julialang.org/u/Iddingsite)
#### Post date: [August 21, 2023, 1:35pm UTC](https://discourse.julialang.org/t/type-of-array-containing-units-from-unitful/103020/4 "2023-08-21T13:35:58Z")

</div>

Thx for the explanation, it works indeed. But I still struggle to extend this to what I want to do.

Basically, let’s say I want to create a function that takes an array with Units of Time and update an array without units from the values in s:

```julia
using Unitful

array_unit = [1.0, 3, 4]u"yr"
array_without_unit = similar(array_unit, Float64)

function remove_unit!(array_without_unit::Vector{Float64}, array_unit::Array{Quantity{Float64, Unitful.𝐓, typeof(Unitful.yr)}, 1})
    array_without_unit .= ustrip.(u"s", array_unit)
end

remove_unit!(array_without_unit, array_unit)

```

That works nicely now. But only if the input has yr and is composed of Float64. How can I generalise that for array containing Real and Time units? I have tried a couple of things, but my understanding is not enough to do it.

First, I’ve replaced Float64 by \<:Real like I would do for an array. This doesn’t work:

```julia
function remove_unit2!(array_without_unit::Vector{Float64}, array_unit::Array{Quantity{<:Real, Unitful.𝐓, typeof(Unitful.yr)}, 1})
    array_without_unit .= ustrip.(u"s", array_unit)
end

remove_unit2!(array_without_unit, array_unit)

```

And for the units par, I’ve tried randomly a few things without much success. Is there an easier way?

---

<div class="post-metadata">

### Author: ![Jollywatt](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jollywatt/32/202198_2.png) [@Jollywatt](https://discourse.julialang.org/u/Jollywatt)
#### Post date: [August 21, 2023, 1:50pm UTC](https://discourse.julialang.org/t/type-of-array-containing-units-from-unitful/103020/5 "2023-08-21T13:50:43Z")

</div>

You don’t actually need any type annotations for this to work, in case that’s not clear.

```julia
function remove_unit!(array_without_unit, array_unit)
    array_without_unit .= ustrip.(u"s", array_unit)
end

```

If you’re wanting to dispatch on the quantity dimension, then given the complexity of Unitful types, perhaps it would be better to use a dictionary to associate dimensions with preferred units …

**Edit**  
See [Highlighted features · Unitful.jl](https://painterqubits.github.io/Unitful.jl/stable/highlights/#Dispatch-on-dimensions) for how to dispatch on dimensions. It looks like you can do

```julia
function remove_unit!(array_without_unit, array_unit::Unitful.Time)
    array_without_unit .= ustrip.(u"s", array_unit)
end

```

---

<div class="post-metadata">

### Author: ![aplavin](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/aplavin/32/222056_2.png) [@aplavin](https://discourse.julialang.org/u/aplavin)
#### Post date: [August 21, 2023, 1:55pm UTC](https://discourse.julialang.org/t/type-of-array-containing-units-from-unitful/103020/6 "2023-08-21T13:55:38Z")

</div>

> [@Iddingsite](#):
>
> I’ve replaced Float64 by \<:Real like I would do for an array

You need to add `<:` to all types in containers:  
`Array{<:Quantity{<:Real, ...}}`

---

<div class="post-metadata">

### Author: ![sostock](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sostock/32/5546_2.png) [@sostock](https://discourse.julialang.org/u/sostock)
#### Post date: [August 21, 2023, 1:59pm UTC](https://discourse.julialang.org/t/type-of-array-containing-units-from-unitful/103020/7 "2023-08-21T13:59:29Z")

</div>

> [@Iddingsite](#):
>
> `array_unit::Array{Quantity{<:Real, Unitful.𝐓, typeof(Unitful.yr)}, 1}`

This doesn’t work because `Quantity{<:Real, Unitful.𝐓, typeof(Unitful.yr)}` is an abstract type, but the array you are passing has is a concrete element type (which is a subtype of the above). You need to add another `<:` like this:

```julia
array_unit::Array{<:Quantity{<:Real, Unitful.𝐓, typeof(Unitful.yr)}, 1}

```

> [@Iddingsite](#):
>
> And for the units par, I’ve tried randomly a few things without much success. Is there an easier way?

Yes, there is the `Unitful.Time` type alias, which matches all quantities with time units:

```julia
array_unit::Array{<:Unitful.Time{<:Real}, 1}

```

---

<div class="post-metadata">

### Author: ![Iddingsite](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/iddingsite/32/31840_2.png) [@Iddingsite](https://discourse.julialang.org/u/Iddingsite)
#### Post date: [August 21, 2023, 2:14pm UTC](https://discourse.julialang.org/t/type-of-array-containing-units-from-unitful/103020/8 "2023-08-21T14:14:55Z")

</div>

Thx a lot for all the responses! I was aware of the Unitful.Time alias, but could not make it work for arrays… @sostock got me covered 👍

I feel like I still need a bit of time to understand all the implications of `<:` and types but I will get there I guess!

---

<div class="post-metadata">

### Author: ![gustaphe](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gustaphe/32/18174_2.png) [@gustaphe](https://discourse.julialang.org/u/gustaphe)
#### Post date: [August 21, 2023, 3:13pm UTC](https://discourse.julialang.org/t/type-of-array-containing-units-from-unitful/103020/9 "2023-08-21T15:13:52Z")

</div>

One nice trick to know about when dealing with Unitful shenanigans is `typeof(1u"yr")`.
