# How to constraint the inner type of \`Val\` by an abstract type

**URL:** <https://discourse.julialang.org/t/how-to-constraint-the-inner-type-of-val-by-an-abstract-type/125944>\
**Category:** General Usage\
**Tags:** parametric-types, val\
**Created:** [February 15, 2025, 5:42pm UTC](https://discourse.julialang.org/t/how-to-constraint-the-inner-type-of-val-by-an-abstract-type/125944 "2025-02-15T17:42:52Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![zsoerenm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/zsoerenm/32/664_2.png) [@zsoerenm](https://discourse.julialang.org/u/zsoerenm)\
**Post date:** [February 15, 2025, 5:42pm UTC](https://discourse.julialang.org/t/how-to-constraint-the-inner-type-of-val-by-an-abstract-type/125944/1 "2025-02-15T17:42:52Z")

</div>

How can I constraint the parametric type within `Val` by an abstract type?

Consider the following function

```julia
using Unitful: Frequency, Hz

function foo(q::Val{Q}) where Q <: Frequency
    return q
end

```

I’d like to Q to be of type `Frequency`.

Unfortunately, the above code errors with:

```julia
julia> foo(Val(1.0Hz))
ERROR: MethodError: no method matching foo(::Val{1.0 Hz})
The function `foo` exists, but no method is defined for this combination of argument types.

Closest candidates are:
  foo(::Val{Q}) where Q<:(Union{Quantity{T, 𝐓^-1, U}, Level{L, S, Quantity{T, 𝐓^-1, U}} where {L, S}} where {T, U})

```

Context: I need to use `Val` in order to unroll a loop.

---

<div class="post-metadata">

**Author:** ![sgaure](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sgaure/32/14779_2.png) [@sgaure](https://discourse.julialang.org/u/sgaure)\
**Post date:** [February 15, 2025, 6:09pm UTC](https://discourse.julialang.org/t/how-to-constraint-the-inner-type-of-val-by-an-abstract-type/125944/2 "2025-02-15T18:09:15Z")

</div>

You can’t dispatch on values, you must check it manually:

```julia
function foo(::Val{q})
    q isa Frequency || error("argument must be Val(Frequency)")
    ... do stuff to q ...
end

```

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [February 16, 2025, 12:08am UTC](https://discourse.julialang.org/t/how-to-constraint-the-inner-type-of-val-by-an-abstract-type/125944/3 "2025-02-16T00:08:31Z")

</div>

> [@sgaure](#):
>
> You can’t dispatch on values

Well, yes, that’s what `Val` is for. But you can’t dispatch on values _and_ their types at the same time.

> [@zsoerenm](#):
>
> `foo(q::Val{Q}) where Q <: Frequency`

The suggested syntax doesn’t make sense here. The operator `<:` is for subtype relationships. `Int32 <: Integer` makes sense, but `32 <: Integer` does not. It would have to be something like

```julia
foo(::Val{Q}) where Q isa Frequency

```

(you normally don’t include the `q` in this case, since `Q` is the actual value.

---

<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:** [February 16, 2025, 4:03am UTC](https://discourse.julialang.org/t/how-to-constraint-the-inner-type-of-val-by-an-abstract-type/125944/4 "2025-02-16T04:03:39Z")

</div>

> [@DNF](#):
>
> `foo(::Val{Q}) where Q isa Frequency`

To be clear, this isn’t valid Julia right now. I think it could be done because `isa` is a `Core` function, but I’m not certain. For now, multiple methods that constrain the `Val` parameter’s type can done by forwarding to a function call on the unwrapped value:

```julia
julia> begin
       foo(::Val{q}) where q = _foo(q)
       _foo(q::Integer) = 0
       _foo(q::AbstractFloat) = 0.0
       end;

julia> foo(Val(1)), foo(Val(1.0))
(0, 0.0)

```

---

<div class="post-metadata">

**Author:** ![nsajko](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nsajko/32/221187_2.png) [@nsajko](https://discourse.julialang.org/u/nsajko)\
**Post date:** [February 16, 2025, 4:25am UTC](https://discourse.julialang.org/t/how-to-constraint-the-inner-type-of-val-by-an-abstract-type/125944/5 "2025-02-16T04:25:20Z")

</div>

> [@Benny](#):
>
> I think it could be done

Related discussion: [constraints on non-type as type parameters · Issue #9580 · JuliaLang/julia · GitHub](https://github.com/JuliaLang/julia/issues/9580)
