# Parameterising types with multiple parameters

**URL:** <https://discourse.julialang.org/t/parameterising-types-with-multiple-parameters/75562>\
**Category:** General Usage\
**Created:** [February 1, 2022, 8:05am UTC](https://discourse.julialang.org/t/parameterising-types-with-multiple-parameters/75562 "2022-02-01T08:05:49Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![torrance](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/torrance/32/38990_2.png) [@torrance](https://discourse.julialang.org/u/torrance)\
**Post date:** [February 1, 2022, 8:05am UTC](https://discourse.julialang.org/t/parameterising-types-with-multiple-parameters/75562/1 "2022-02-01T08:05:50Z")

</div>

I have a type parameterised by floating point precision, something like this:

```julia
struct MyType{T <: AbstractFloat}
    x::T
    data::Array{T}
end

```

Note that it’s import that the type of x and the type of the array data match.

And I want this to _also_ work on the GPU, so basically I also want this to be valid:

```julia
struct MyType{T <: AbstractFloat}
    x::T
    data::CuArray{T}
end

```

My natural attempt to resolve this is to provide an additional type parameter, something like:

```julia
struct MyType{T <: AbstractFloat, P <: AbstractArray}
    x::T
    data::P{T}
end

```

However, Julia complains `TypeError: in Type{...} expression, expected UnionAll, got a value of type TypeVar`.

Two questions:

1. Why isn’t this valid?
2. What is the most natural (and simple) way to express this kind of type and constraint?

---

<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:** [February 1, 2022, 8:12am UTC](https://discourse.julialang.org/t/parameterising-types-with-multiple-parameters/75562/2 "2022-02-01T08:12:52Z")

</div>

1. (Simplified) It doesn’t work because `P` could already match a concrete type. For example, `P` could be `Array{Float64,1}`, so `P{T}` is not valid.
2. Use

```julia
struct MyType{T <: AbstractFloat, P <: AbstractArray{T}}
    x::T
    data::P
end

```

instead.

Note also that in your original example, `data::Array{T}` is not a concrete type (the second type parameter is missing), so this would slow down your code.

---

<div class="post-metadata">

**Author:** ![goerch](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/goerch/32/29122_2.png) [@goerch](https://discourse.julialang.org/u/goerch)\
**Post date:** [February 1, 2022, 8:13am UTC](https://discourse.julialang.org/t/parameterising-types-with-multiple-parameters/75562/3 "2022-02-01T08:13:28Z")

</div>

The following might help:

```julia
struct MyType{T <: AbstractFloat, P <: AbstractArray{T}}
    x::T
    data::P
end

x = MyType(1.0, Vector{Float64}(undef, 1))
println(typeof(x))
y = MyType(1.0, Matrix{Float64}(undef, 1, 1))
println(typeof(y))
z = MyType(1.0, Matrix{Int}(undef, 1, 1))
println(typeof(z))

```

yielding

```julia
MyType{Float64, Vector{Float64}}
MyType{Float64, Matrix{Float64}}
ERROR: LoadError: MethodError: no method matching MyType(::Float64, ::Matrix{Int64})

```

---

<div class="post-metadata">

**Author:** ![torrance](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/torrance/32/38990_2.png) [@torrance](https://discourse.julialang.org/u/torrance)\
**Post date:** [February 1, 2022, 8:23am UTC](https://discourse.julialang.org/t/parameterising-types-with-multiple-parameters/75562/4 "2022-02-01T08:23:32Z")

</div>

Thank you! Exactly what I was looking for.
