# Impose two conditions on parametric type

**URL:** <https://discourse.julialang.org/t/impose-two-conditions-on-parametric-type/75028>\
**Category:** General Usage\
**Tags:** parametric-types\
**Created:** [January 22, 2022, 11:21am UTC](https://discourse.julialang.org/t/impose-two-conditions-on-parametric-type/75028 "2022-01-22T11:21:08Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![sstroemer](https://avatars.discourse-cdn.com/v4/letter/s/a88e4f/32.png) [@sstroemer](https://discourse.julialang.org/u/sstroemer)\
**Post date:** [January 22, 2022, 11:21am UTC](https://discourse.julialang.org/t/impose-two-conditions-on-parametric-type/75028/1 "2022-01-22T11:21:08Z")

</div>

I have a type defined as `_NumericalInput = Union{Float64, Vector{Float64}}`.  
I’d like to implement a function like:

```julia
get(x::Float64, t::Int) = x
get(x::Vector{Float64}, t::Int) = x[t]

```

But as soon as I change `_NumericalInput`, (i.e. including `Int64`) I would need to remember to get back to that and change it. So what I would like to do is:

```julia
get(x::T, t::Int) where T <: _NumericalInput = x
get(x::T, t::Int) where T <: _NumericalInput AND T <: Vector = x[t]

```

Basically implementing `get(...)` for all types that are a `_NumericalInput` conditioned on whether they are subtype of `Vector` or not.

---

<div class="post-metadata">

**Author:** ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)\
**Post date:** [January 22, 2022, 11:45am UTC](https://discourse.julialang.org/t/impose-two-conditions-on-parametric-type/75028/2 "2022-01-22T11:45:29Z")

</div>

> [@sstroemer](#):
>
> ```julia
> get(x::NumericalInput,t) = _get(x,t)
> _get(x::Float64, t::Int) = x
> _get(x::AbstractVector{Float64}, t::Int) = x[t]
> 
> ```

You could use a barrier like the above, or an assertion. But this is not very idiomatic, why not just make the functions generic for numbers and vectors?

---

<div class="post-metadata">

**Author:** ![sstroemer](https://avatars.discourse-cdn.com/v4/letter/s/a88e4f/32.png) [@sstroemer](https://discourse.julialang.org/u/sstroemer)\
**Post date:** [January 22, 2022, 12:17pm UTC](https://discourse.julialang.org/t/impose-two-conditions-on-parametric-type/75028/3 "2022-01-22T12:17:39Z")

</div>

> You could use a barrier like the above, or an assertion.

The barrier is a nice idea, that way it at least works. I still feel though this does feel a bit unintuitive (or rather non-elegant).

> But this is not very idiomatic, why not just make the functions generic for numbers and vectors?

This would allow me to call `get(["a"], 1)`. But that should fail, since `Vector{String}` is not a valid `_NumericalInput`.

* * *

Maybe there is a way to contruct a “conditional subtype”? I know I can access all vector types for example through:

```julia
[t for t in Base.uniontypes(_NumericalInput) if t <: Vector]

```

Is there a way to create a subtype (at compile time) from that? Basically creating this:

```julia
_NumericalVectorInput = Union{t for t in Base.uniontypes(_NumericalInput) if t <: Vector}

```

and using `get(x::_NumericalVectorInput, t::Int)` afterwards.

---

<div class="post-metadata">

**Author:** ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)\
**Post date:** [January 22, 2022, 12:23pm UTC](https://discourse.julialang.org/t/impose-two-conditions-on-parametric-type/75028/4 "2022-01-22T12:23:43Z")

</div>

Why not just `AbstractVector{<: Number}` ? Do you really want to restrict to not accept Float32 for instance?

Many times is advantageous to just let the signature generic and let the error appear down the line. (Most Julia code is written like that)

And if you want a more precise error message add a barrier on the very top of the user input to assert the type of variable that are supported.

---

<div class="post-metadata">

**Author:** ![sstroemer](https://avatars.discourse-cdn.com/v4/letter/s/a88e4f/32.png) [@sstroemer](https://discourse.julialang.org/u/sstroemer)\
**Post date:** [January 22, 2022, 12:34pm UTC](https://discourse.julialang.org/t/impose-two-conditions-on-parametric-type/75028/5 "2022-01-22T12:34:29Z")

</div>

> Why not just `AbstractVector{<: Number}` ? Do you really want to restrict to not accept Float32 for instance?

It seems like this would be the best approach for my current problem. Thanks!

> Do you really want to restrict to not accept Float32 for instance?

It was more meant to prevent erroneous inputs as either `Float` or `Int` when only one of them is allowed. But I can check for that elsewhere and not restrict the type, which was probably a stupid idea to begin with.

_(but, on a general scope, it essentially comes down to a workaround, due to the parametric type system being strangely restricting… allowing ranges with S \<: T \<: U, but not multiple conditions?!)_
