# How to extract the Type of a generic struct and use it for pattern matching?

**URL:** <https://discourse.julialang.org/t/how-to-extract-the-type-of-a-generic-struct-and-use-it-for-pattern-matching/42371>\
**Category:** Internals & Design\
**Tags:** question\
**Created:** [July 1, 2020, 1:59pm UTC](https://discourse.julialang.org/t/how-to-extract-the-type-of-a-generic-struct-and-use-it-for-pattern-matching/42371 "2020-07-01T13:59:54Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![Junars](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/junars/32/16094_2.png) [@Junars](https://discourse.julialang.org/u/Junars)\
**Post date:** [July 1, 2020, 1:59pm UTC](https://discourse.julialang.org/t/how-to-extract-the-type-of-a-generic-struct-and-use-it-for-pattern-matching/42371/1 "2020-07-01T13:59:54Z")

</div>

I’m a novice, someone could help?  
here’s the demo code I want:

```julia
struct Foo{T <: Real}
	cont::String    
end

bar = Foo{Int}("test")

typeof(bar) == Foo{Int} # true

# is there a package can do pattern match like this?
@match typeof(bar) begin
    Foo{T} => @match T begin
        Float => # do something
        Int => # do something
    end

    Foo1{T} => ...
end

```

---

<div class="post-metadata">

**Author:** ![Junars](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/junars/32/16094_2.png) [@Junars](https://discourse.julialang.org/u/Junars)\
**Post date:** [July 1, 2020, 2:11pm UTC](https://discourse.julialang.org/t/how-to-extract-the-type-of-a-generic-struct-and-use-it-for-pattern-matching/42371/2 "2020-07-01T14:11:19Z")

</div>

May be I should convert `Foo{T}` to string then extract the substring T ! I can use string for pattern match! This may make sense!

---

<div class="post-metadata">

**Author:** ![rdeits](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rdeits/32/286_2.png) [@rdeits](https://discourse.julialang.org/u/rdeits)\
**Post date:** [July 1, 2020, 2:24pm UTC](https://discourse.julialang.org/t/how-to-extract-the-type-of-a-generic-struct-and-use-it-for-pattern-matching/42371/3 "2020-07-01T14:24:00Z")

</div>

You can access the `T` field within a function using a `where` clause:

```julia
function do_stuff(foo::Foo{T}) where {T}
  println("The parameter type is: $T")
end

```

and you can directly compare `T` in an `if` statement to choose different behaviors based on the particular type.

However, it’s more common in Julia to use multiple dispatch to implement this kind of type-based switching. For example, you might do:

```julia
function do_stuff(foo::Foo{Float64}) # only applies to exactly Foo{Float64}
  do_something()
end

function do_stuff(foo::Foo{T}) where {T <: Integer} # applies for any kind of integer
  do_something()
end

function do_stuff(foo::Foo) # applies to any `Foo`
  do_something()
end

```

Julia will always pick the most specific matching method, so `do_stuff(Foo{Int}())` will call the `T <: Integer` version, while `do_stuff(Foo{String}())` will call the generic `do_stuff(foo::Foo)` method.

---

<div class="post-metadata">

**Author:** ![rdeits](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rdeits/32/286_2.png) [@rdeits](https://discourse.julialang.org/u/rdeits)\
**Post date:** [July 1, 2020, 2:25pm UTC](https://discourse.julialang.org/t/how-to-extract-the-type-of-a-generic-struct-and-use-it-for-pattern-matching/42371/4 "2020-07-01T14:25:40Z")

</div>

> [@Junars](#):
>
> May be I should convert `Foo{T}` to string then extract the substring T ! I can use string for pattern match!

No, don’t do that 🙂

Converting types to strings is almost never useful or necessary in Julia. You can easily get the actual _type_ T with a `where` clause:

```julia
julia> function get_parameter(foo::Foo{T}) where {T}
        T
      end
get_parameter (generic function with 1 method)

julia> f = Foo{Int}()
Foo{Int64}()

julia> get_parameter(f)
Int64

julia> g = Foo{Float64}()
Foo{Float64}()

julia> get_parameter(g)
Float64

```

---

<div class="post-metadata">

**Author:** ![Junars](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/junars/32/16094_2.png) [@Junars](https://discourse.julialang.org/u/Junars)\
**Post date:** [July 1, 2020, 2:50pm UTC](https://discourse.julialang.org/t/how-to-extract-the-type-of-a-generic-struct-and-use-it-for-pattern-matching/42371/5 "2020-07-01T14:50:51Z")

</div>

Thank you very much sir! Your solution is really help. But I’m in a situation:

```julia
abstract type Term end

abstract type AbstractStatement <: Term end
abstract type S1 <: AbstractStatement end
abstract type S2 <: AbstractStatement end

abstract type AbstractCompound <: Term end
abstract type C1 <: AbstractCompound end
abstract type C2 <: AbstractCompound end

struct Statement{T <: AbstractStatement} <: Term
    cont::String
end

struct Compound{T <: AbstractCompound} <: Term
    cont::String
end

function foo(t::Term)
	# t could be Statement or Compound
    @match typeof(t) begin
    	# T could be S1,S2 or C1,C2
        Statement{T} => @match T begin
            S1 => # do something
            S2 => # do something
        end
        Compound{T} => @match T begin
            C1 => # do something
            C2 => # do something
        end
    end
end

```

forgive me for my lazy and greedy. I want to do more things but less code. 😂

---

<div class="post-metadata">

**Author:** ![mcabbott](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mcabbott/32/6603_2.png) [@mcabbott](https://discourse.julialang.org/u/mcabbott)\
**Post date:** [July 1, 2020, 2:54pm UTC](https://discourse.julialang.org/t/how-to-extract-the-type-of-a-generic-struct-and-use-it-for-pattern-matching/42371/6 "2020-07-01T14:54:48Z")

</div>

If you don’t want to write separate methods, you are free to test `if t isa S1; #stuff; elseif t isa C1` inside `foo`. The branches should compile away.

---

<div class="post-metadata">

**Author:** ![simeonschaub](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/simeonschaub/32/216566_2.png) [@simeonschaub](https://discourse.julialang.org/u/simeonschaub)\
**Post date:** [July 1, 2020, 2:56pm UTC](https://discourse.julialang.org/t/how-to-extract-the-type-of-a-generic-struct-and-use-it-for-pattern-matching/42371/7 "2020-07-01T14:56:30Z")

</div>

You can just use dispatch here too, i.e:

```julia
foo(x::S1) = ...
foo(x::S2) = ...
foo(x::C1) = ...
foo(x::C2) = ...

```

(FYI, it’s generally preferred to post code as text inside triple quotes (```) instead of as screenshots, because it saves a lot of bandwidth and it’s also much easier to copy your code in order to help you.)

---

<div class="post-metadata">

**Author:** ![Junars](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/junars/32/16094_2.png) [@Junars](https://discourse.julialang.org/u/Junars)\
**Post date:** [July 1, 2020, 3:00pm UTC](https://discourse.julialang.org/t/how-to-extract-the-type-of-a-generic-struct-and-use-it-for-pattern-matching/42371/8 "2020-07-01T15:00:25Z")

</div>

yes, I should write separate functions!

---

<div class="post-metadata">

**Author:** ![Junars](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/junars/32/16094_2.png) [@Junars](https://discourse.julialang.org/u/Junars)\
**Post date:** [July 1, 2020, 3:02pm UTC](https://discourse.julialang.org/t/how-to-extract-the-type-of-a-generic-struct-and-use-it-for-pattern-matching/42371/9 "2020-07-01T15:02:31Z")

</div>

yeah, I should practice more to get used to Multiple Dispatch!

---

<div class="post-metadata">

**Author:** ![Junars](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/junars/32/16094_2.png) [@Junars](https://discourse.julialang.org/u/Junars)\
**Post date:** [July 1, 2020, 3:03pm UTC](https://discourse.julialang.org/t/how-to-extract-the-type-of-a-generic-struct-and-use-it-for-pattern-matching/42371/10 "2020-07-01T15:03:42Z")

</div>

and, I will use markdown to post my questions.

---

<div class="post-metadata">

**Author:** ![Junars](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/junars/32/16094_2.png) [@Junars](https://discourse.julialang.org/u/Junars)\
**Post date:** [July 1, 2020, 3:06pm UTC](https://discourse.julialang.org/t/how-to-extract-the-type-of-a-generic-struct-and-use-it-for-pattern-matching/42371/11 "2020-07-01T15:06:41Z")

</div>

Thank you all very much! This may be a stupid question, but you are really nice people!
