# Membership of Type{T}

**URL:** https://discourse.julialang.org/t/membership-of-type-t/37654
**Category:** Internals & Design
**Tags:** question
**Created:** [April 15, 2020, 4:41pm UTC](https://discourse.julialang.org/t/membership-of-type-t/37654 "2020-04-15T16:41:44Z")
**Posts on this page:** 4
**Page:** 1

<div class="post-metadata">

### Author: ![ckfinite](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ckfinite/32/8341_2.png) [@ckfinite](https://discourse.julialang.org/u/ckfinite)
#### Post date: [April 15, 2020, 4:41pm UTC](https://discourse.julialang.org/t/membership-of-type-t/37654/1 "2020-04-15T16:41:45Z")

</div>

I’ve ran into a type membership question with Type{T}, which seems to be behaving counterintuitively.

According to the documentation, Type{T} is the singleton consisting of the type T itself. Thus, `isa(Int, Type{T})` returns true. However, if we combine this with a tuple, the relationship breaks down, as `isa((Int,), Tuple{Type{Int}})` returns false. What is the logic as to why this is happening?

Digging into it more, the implementation of [isa](https://github.com/JuliaLang/julia/blob/3bcedb214e894c2e183dababe5eefb2b17c4feb4/src/subtype.c#L2059) seems to provide some explanation. If the lhs of an `isa` call is a `Type` and the RHS is a `DataType` that is not superficially a `Type{T}` then it will _always_ return false. This explains what’s happening in this particular case, but it’s not clear to me why this is correct.

---

<div class="post-metadata">

### Author: ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)
#### Post date: [April 15, 2020, 5:38pm UTC](https://discourse.julialang.org/t/membership-of-type-t/37654/2 "2020-04-15T17:38:47Z")

</div>

> [@ckfinite](#):
>
> as `isa((Int,), Tuple{Type{Int}})` returns false. What is the logic as to why this is happening?

It is very likely that you are looking for

```julia
julia> isa(Tuple{Int}, Type{Tuple{Int}})
true

```

I would recommend thinking of `Type{T}` as sugar for dispatching on a type value `T`, not as part of the type hierarchy. See

> [@How to interpret "Type{T} where T" in Julias Type-system](https://discourse.julialang.org/t/how-to-interpret-type-t-where-t-in-julias-type-system/37402):
>
> I have some problems parsing the Julias type-system… and I came up with a few questions. [Docs - Types](https://docs.julialang.org/en/v1/manual/types/#man-singleton-types-1): “Type{T} is an abstract type whose only instance is the object T” How can an abstract type have instances?? As far as I can understand is Type{T} kind of a special thing that has the following defining property: " isa(A,Type{B}) is true iff A and B are the same object and that object is a type". Why has this special thing DataType, Union etc. as subtypes? julia\> subtypes(Type) 4-element…

---

<div class="post-metadata">

### Author: ![ckfinite](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ckfinite/32/8341_2.png) [@ckfinite](https://discourse.julialang.org/u/ckfinite)
#### Post date: [April 15, 2020, 5:56pm UTC](https://discourse.julialang.org/t/membership-of-type-t/37654/3 "2020-04-15T17:56:43Z")

</div>

Hmm, that’s not exactly the semantics I’m interested in. What I’m looking for in (for example) `Tuple{Type{Int}, Bool}}` is the type that describes the set of tuples whose first element is the type `Int` and whose second element is an instance of a boolean. If I were to write this as the type `Type{Tuple{Int, Bool}}`, then that’s the singleton that contains the tuple type, rather than the type of tuples with determined internal values.

> I would recommend thinking of `Type{T}` as sugar for dispatching on a type value `T` , not as part of the type hierarchy.

The problem is that I’m working on a model of dispatch (for static analysis) and need to be able to simulate dispatch over my own representation of the currently available methods. The logical way to do this would be to build method signature equivalent tuple types and then use `isa` and subtyping to filter and do specificity ranking. However, the behaviour of `Type{T}` makes this challenging, because a `Type{T}` inside of a tuple seems to behave differently than a `Type{T}` outside of said tuple.

The alternative is to break apart the arguments to methods and test them independently, which gets around this particular issue, but creates new challenges (e.g. with the diagonal rule) where I need to make sure that type variable bounds are propagated properly through the membership testing.

---

<div class="post-metadata">

### Author: ![ckfinite](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ckfinite/32/8341_2.png) [@ckfinite](https://discourse.julialang.org/u/ckfinite)
#### Post date: [April 15, 2020, 9:34pm UTC](https://discourse.julialang.org/t/membership-of-type-t/37654/4 "2020-04-15T21:34:21Z")

</div>

Ah, I solved my problem, though it’s not a general solution to `Type{T}` oddness. In my particular case, I realized that `arg_type_tuple` isn’t equivalent to `typeof` in the case of Type arguments, so I can just duplicate that functionality and get semantically equivalent dispatch.
