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

```
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:

```
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:

```
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:

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

sostock
February 1, 2022, 8:12am
#2
(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.
Use```
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.

goerch
February 1, 2022, 8:13am
#3
The following might help:

```
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

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

Thank you! Exactly what I was looking for.