# Usage of Correct Types in Array

**URL:** https://discourse.julialang.org/t/usage-of-correct-types-in-array/29142
**Category:** New to Julia
**Created:** [September 25, 2019, 3:37am UTC](https://discourse.julialang.org/t/usage-of-correct-types-in-array/29142 "2019-09-25T03:37:27Z")
**Posts on this page:** 7
**Page:** 1

<div class="post-metadata">

### Author: ![ZQ\_Li](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/zq_li/32/4954_2.png) [@ZQ\_Li](https://discourse.julialang.org/u/ZQ_Li)
#### Post date: [September 25, 2019, 3:37am UTC](https://discourse.julialang.org/t/usage-of-correct-types-in-array/29142/1 "2019-09-25T03:37:27Z")

</div>

Hi,

I want to write a function that can take matrix composing of both int and float and return if it is a upper triangle matrix or not:

```julia
function isUpperTriangle(A::Array{Number, 2}, tol::Number=1e-3)::Bool
    for i in CartesianIndices(A)
        if i[1] > i[2]
            if A[i[1], i[2]] > tol
                return false
            end
        end
    end
    true
end

```

However, when I test it out like:

```julia
tt = [1 2 3; 0 3 4; 0 0 5]
isUpperTriangle(tt) # Should return true

```

it returns:

```julia
julia> isUpperTriangle(tt) # Should return true
ERROR: MethodError: no method matching isUpperTriangle(::Array{Int64,2})
Closest candidates are:
  isUpperTriangle(::Array{Number,2}) at REPL[1]:2
  isUpperTriangle(::Array{Number,2}, ::Number) at REPL[1]:2
Stacktrace:
 [1] top-level scope at REPL[3]:1

```

If I change the type annotation from `Number` to `<:Number` then it works fine. The thing I don’t understand is I can use the annotation like this:

```julia
function test_fun(x::Number)
    println(x)
end

```

and that accepts both Int and Float fine. Why is that?

Thank you!

---

<div class="post-metadata">

### Author: ![Oscar\_Smith](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oscar_smith/32/25343_2.png) [@Oscar\_Smith](https://discourse.julialang.org/u/Oscar_Smith)
#### Post date: [September 25, 2019, 4:12am UTC](https://discourse.julialang.org/t/usage-of-correct-types-in-array/29142/2 "2019-09-25T04:12:43Z")

</div>

Types in Julia are invariant. Thus `x{A}<:x{B}` implies `A===B`. [java - Covariance, Invariance and Contravariance explained in plain English? - Stack Overflow](https://stackoverflow.com/questions/8481301/covariance-invariance-and-contravariance-explained-in-plain-english) is a pretty good rundown of the difference.

---

<div class="post-metadata">

### Author: ![ry-dgel](https://avatars.discourse-cdn.com/v4/letter/r/2acd7d/32.png) [@ry-dgel](https://discourse.julialang.org/u/ry-dgel)
#### Post date: [September 25, 2019, 5:40am UTC](https://discourse.julialang.org/t/usage-of-correct-types-in-array/29142/3 "2019-09-25T05:40:35Z")

</div>

As mentioned, [parametric types](https://docs.julialang.org/en/v1/manual/types/index.html#Parametric-Types-1) “Type{T}” with different values for T are never consided the same type.

What you can do is explicitely initiate your input array as:

> Array{Number,2}([1 2 3; 0 3 4; 0 0 5])

---

<div class="post-metadata">

### Author: ![Oscar\_Smith](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oscar_smith/32/25343_2.png) [@Oscar\_Smith](https://discourse.julialang.org/u/Oscar_Smith)
#### Post date: [September 25, 2019, 5:41am UTC](https://discourse.julialang.org/t/usage-of-correct-types-in-array/29142/4 "2019-09-25T05:41:40Z")

</div>

The better approach is to define `isUpper` using `<:Number`

---

<div class="post-metadata">

### Author: ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)
#### Post date: [September 25, 2019, 6:55am UTC](https://discourse.julialang.org/t/usage-of-correct-types-in-array/29142/5 "2019-09-25T06:55:47Z")

</div>

> [@ry-dgel](#):
>
> What you can do is explicitely initiate your input array as:
> 
> > `Array{Number,2}([1 2 3; 0 3 4; 0 0 5])`

This is 8x slower on my laptop, so I would not recommended this in place of just doing things the proper way.

---

<div class="post-metadata">

### Author: ![tomerarnon](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tomerarnon/32/3170_2.png) [@tomerarnon](https://discourse.julialang.org/u/tomerarnon)
#### Post date: [September 25, 2019, 8:52am UTC](https://discourse.julialang.org/t/usage-of-correct-types-in-array/29142/6 "2019-09-25T08:52:28Z")

</div>

To clarify, the proper way is the following:

```julia
function isUpperTriangle(A::Array{<:Number, 2}, tol::Number=1e-3)::Bool
    for i in CartesianIndices(A)
        if i[1] > i[2]
            if A[i[1], i[2]] > tol
                return false
            end
        end
    end
    true
end

julia> tt = [1 2 3; 0 3 4; 0 0 5];

julia> isUpperTriangle(tt)
true

```

The only difference is the `Array{<:Number, 2}` in the function signature instead of `Array{Number, 2}`.

* * *

By the way, it is often useful to write methods that are as general as possible (maybe not in this case, but that’s up to you). You could get the same functionality with this more general function:

```julia
function isUpperTriangle(A::AbstractMatrix, tol = 1e-3)
    for i in CartesianIndices(A)
        if i[1] > i[2]
           if A[i] > tol
               return false
           end
       end
   end
   true
end

```

Now this still works:

```julia
julia> isUpperTriangle(tt)
true

```

But now so does any matrix type, as long as `tol` was something comparable with the elements of `A`. Note below that `tt'` (tt transpose) is not an `Array`, but the function still works.

```julia
julia> isUpperTriangle(tt')
false

```

The following will also work

```julia
julia> isUpperTriangle(Char.(tt), Char(1))
true

julia> isUpperTriangle(Char.(tt'), Char(1))
false

```

---

<div class="post-metadata">

### Author: ![tomerarnon](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tomerarnon/32/3170_2.png) [@tomerarnon](https://discourse.julialang.org/u/tomerarnon)
#### Post date: [September 30, 2019, 7:18am UTC](https://discourse.julialang.org/t/usage-of-correct-types-in-array/29142/7 "2019-09-30T07:18:34Z")

</div>

> [@ZQ\_Li](#):
>
> If I change the type annotation from `Number` to `<:Number` then it works fine. The thing I don’t understand is I can use the annotation like this:
> 
> ```julia
> function test_fun(x::Number)
> println(x)
> end
> 
> ```
> 
> and that accepts both Int and Float fine. Why is that?

This is because `Number` is an abstract type and `Float64 <: Number`. Therefore a function written for `x::Number` can be compiled for `Float64`. However, `Vector{Number}` is a _concrete_ type, and `Vector{Float64}` is therefore _not_ a subtype of `Vector{Number}`. Since it is not a subtype, a function written for `Vector{Number}` cannot accept `Vector{Float64}`. This is why you must specify `Vector{<:Number}`.

By the way, this can be understood by realizing that it is possible to promote an array of `Float64`s to an array of `Numbers`, but it is never possible to promote a single `Float64` to a `Number`. If a type can “exist” as an object, it is necessarily concrete.

```julia
julia> typeof(Vector{Number}([1.0,2.0]))
Array{Number,1}

julia> typeof(Number(1.0))
Float64

```
