# Inhibit same type parameters

**URL:** <https://discourse.julialang.org/t/inhibit-same-type-parameters/15147>\
**Category:** General Usage\
**Tags:** question, type, parametric-types\
**Created:** [September 18, 2018, 8:53pm UTC](https://discourse.julialang.org/t/inhibit-same-type-parameters/15147 "2018-09-18T20:53:59Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![singularitti](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/singularitti/32/17678_2.png) [@singularitti](https://discourse.julialang.org/u/singularitti)\
**Post date:** [September 18, 2018, 8:53pm UTC](https://discourse.julialang.org/t/inhibit-same-type-parameters/15147/1 "2018-09-18T20:53:59Z")

</div>

For example, I have 4 types `A`, `B`, `C` and `D`, which can be filled in a parametric type `P`.

```julia
const U = Union{A, B, C, D}

struct P{F <: U, S <: U}
    a::Vector
    b::Vector
    function P{F, S}(a, b) where {F, S}
        F == S && throw(ArgumentError("The parameters must have different types!"))
    end
end

```

However, what I want is that `F` cannot be equal to `S`. How can I do that if I do not want specify it in the inner constructor? What if I just want to inhibit statements like `P{A, A}`, `P{B, B}`, etc., even without parameters `(a, b)` because generating `a` and `b` can take time?

---

<div class="post-metadata">

**Author:** ![tkoolen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tkoolen/32/1603_2.png) [@tkoolen](https://discourse.julialang.org/u/tkoolen)\
**Post date:** [September 18, 2018, 9:40pm UTC](https://discourse.julialang.org/t/inhibit-same-type-parameters/15147/2 "2018-09-18T21:40:33Z")

</div>

There’s no way to make it so that simply writing `P{A, A}` errors, if that’s what you want. If you call `dump(P)`, you get

```julia
julia> dump(P)
UnionAll
  var: TypeVar
    name: Symbol F
    lb: Core.TypeofBottom Union{}
    ub: Union{A, B, C, D}
  body: UnionAll
    var: TypeVar
      name: Symbol S
      lb: Core.TypeofBottom Union{}
      ub: Union{A, B, C, D}
    body: P{F<:Union{A, B, C, D},S<:Union{A, B, C, D}} <: Any
      a::Array{T,1} where T
      b::Array{T,1} where T

```

This shows how `UnionAll`s like `P` are represented in Julia. You can have upper bounds (`ub`) and lower bounds (`lb`) on type variables, but `UnionAll` itself does not support more complicated constraints, probably to limit the computational complexity of type system queries (but I’m far from an expert on this subject).
