# Defining a type that mirrors a built-in container

**URL:** https://discourse.julialang.org/t/defining-a-type-that-mirrors-a-built-in-container/75472
**Category:** General Usage
**Created:** [January 30, 2022, 7:04pm UTC](https://discourse.julialang.org/t/defining-a-type-that-mirrors-a-built-in-container/75472 "2022-01-30T19:04:52Z")
**Posts on this page:** 5
**Page:** 1

<div class="post-metadata">

### Author: ![rpmuller](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rpmuller/32/2262_2.png) [@rpmuller](https://discourse.julialang.org/u/rpmuller)
#### Post date: [January 30, 2022, 7:04pm UTC](https://discourse.julialang.org/t/defining-a-type-that-mirrors-a-built-in-container/75472/1 "2022-01-30T19:04:52Z")

</div>

I’d like to define a type that mirrors a built-in type. Normally when I want to do this, I just define a struct with a member `l` that has the type I want:

```
struct mylist1
    l::Array{Int32}
end

```

and then define some methods that use mylist1.

```
function(myl::mylist1) = do_something(myl.l)

```

But there must be some way to do this without creating a member to shadow the original type, right? I essentially want to define a type that acts like:

```
struct mylist2 <: Array{Int32} end

```

but that returns

```
ERROR: invalid subtyping in definition of mylist2

```

I saw some notes in the docs that concrete types may not subtype each other, but neither

```
struct mylist2 <: AbstractArray{Int32} end

```

nor

```
 struct mylist2 <: AbstractArray end

```

work either. What’s the proper way to do this in Julia?

---

<div class="post-metadata">

### Author: ![Benny](https://avatars.discourse-cdn.com/v4/letter/b/49beb7/32.png) [@Benny](https://discourse.julialang.org/u/Benny)
#### Post date: [January 30, 2022, 7:21pm UTC](https://discourse.julialang.org/t/defining-a-type-that-mirrors-a-built-in-container/75472/2 "2022-01-30T19:21:45Z")

</div>

Basically this is because `AbstractArray` is a [parametric abstract type](https://docs.julialang.org/en/v1/manual/types/#Parametric-Abstract-Types), and when subtyping one, you need to account for all the parameters. If you didn’t, the supertype would be ambiguous (is `mylist2` a subtype of both `AbstractArray{Int32, 1}` and `AbstractArray{Int32, 3}`?). So, `struct mylist2{N} <: AbstractArray{Int32, N} end` or `struct mylist2 <: AbstractArray{Int32, 1} end` would work.

Also, `Array{Int32}` isn’t a concrete type, the implicit dimensions parameter `N` is not specified so it’s a parametric composite type, which is an abstract type representing a set of concrete types. The difference from a parametric abstract type is that when you specify all the parameters, you must get a concrete type like `Array{Int32, 2}`, whereas `AbstractArray{Int32, 2}` is still abstract. You probably can infer this, but `struct mylist2{N} <: Array{Int32, N} end` would not work because a concrete `mylist2{1}` cannot be a subtype of a concrete `Array{Int32, 1}`.

---

<div class="post-metadata">

### Author: ![rpmuller](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rpmuller/32/2262_2.png) [@rpmuller](https://discourse.julialang.org/u/rpmuller)
#### Post date: [January 30, 2022, 7:32pm UTC](https://discourse.julialang.org/t/defining-a-type-that-mirrors-a-built-in-container/75472/3 "2022-01-30T19:32:26Z")

</div>

Thanks. Now this works:

```
struct mylist2 <: AbstractArray{Int32,1} end

```

But calling it doesn’t:

```
a = mylist2()

Error showing value of type mylist2:
ERROR: MethodError: no method matching size(::mylist2)
Closest candidates are:
  size(::AbstractArray{T, N}, ::Any) where {T, N} at /Applications/Julia-1.7.app/Contents/Resources/julia/share/julia/base/abstractarray.jl:42
  size(::Union{LinearAlgebra.Adjoint{T, var"#s859"}, LinearAlgebra.Transpose{T, var"#s859"}} where {T, var"#s859"<:(AbstractVector)}) at /Applications/Julia-1.7.app/Contents/Resources/julia/share/julia/stdlib/v1.7/LinearAlgebra/src/adjtrans.jl:172
  size(::Union{LinearAlgebra.Adjoint{T, var"#s859"}, LinearAlgebra.Transpose{T, var"#s859"}} where {T, var"#s859"<:(AbstractMatrix)}) at /Applications/Julia-1.7.app/Contents/Resources/julia/share/julia/stdlib/v1.7/LinearAlgebra/src/adjtrans.jl:173

```

Am I still doing something wrong?

---

<div class="post-metadata">

### Author: ![Benny](https://avatars.discourse-cdn.com/v4/letter/b/49beb7/32.png) [@Benny](https://discourse.julialang.org/u/Benny)
#### Post date: [January 30, 2022, 7:43pm UTC](https://discourse.julialang.org/t/defining-a-type-that-mirrors-a-built-in-container/75472/4 "2022-01-30T19:43:15Z")

</div>

Actually, calling it works e.g. `a = mylist2(); typeof(a)`. The error happens when you try to _display_ the object on the REPL. Many existing methods figure out how stuff is displayed, and for something like `struct mylist end`, `mylist()` would simply display `mylist()`. However, `mylist2` is an `AbstractArray`, and since that’s normally for rectangular grids of elements, it gets dispatched to a different method.

The first hiccup that method ran into is the lack of the `size` method. That is one of the [`AbstractArray` interface methods](https://docs.julialang.org/en/v1/manual/interfaces/#man-interface-array); interface methods get used by all other methods, so they sort of delineate what something “is” (that something may not even be an abstract type e.g. iterables). If you define these, `AbstractArray` methods should work for you.

Personally, though, I’m a bit lazier and go with the composition approach of `mylist1` instead of the inheritance approach of `mylist2`. I’d just make a `get_array(x::mylist1) = x.l` and do calls like `do_something(get_array(x))`.

---

<div class="post-metadata">

### Author: ![rpmuller](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rpmuller/32/2262_2.png) [@rpmuller](https://discourse.julialang.org/u/rpmuller)
#### Post date: [January 30, 2022, 9:14pm UTC](https://discourse.julialang.org/t/defining-a-type-that-mirrors-a-built-in-container/75472/5 "2022-01-30T21:14:33Z")

</div>

Gotcha. Thanks very much. I’ll stick with composition. Thanks!
