# @match type?

**URL:** <https://discourse.julialang.org/t/match-type/1232>\
**Category:** General Usage\
**Tags:** match\
**Created:** [December 31, 2016, 8:52pm UTC](https://discourse.julialang.org/t/match-type/1232 "2016-12-31T20:52:48Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![stustd](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stustd/32/21430_2.png) [@stustd](https://discourse.julialang.org/u/stustd)\
**Post date:** [December 31, 2016, 8:52pm UTC](https://discourse.julialang.org/t/match-type/1232/1 "2016-12-31T20:52:48Z")

</div>

I’m utterly confused why the following code doesn’t produce identical results (i.e. selecting on type with @match (Match.jl) or if…elseif…end). With @match (get\_fmt1) regardless of the actual type, always an integer type is matched…? More insight much appreciated.

```julia
using Match

function get_fmt1(a)
  T = typeof(a)
  S = supertype(T)
  println("Ta, Sa = $T, $S")
  fmt(a) = @match S begin
    # Signed => "d"
    Integer || Signed || Unsigned || Bool || BigInt => "d"
    AbstractFloat => "f"
    AbstractString => "s"
    _,Any => "s"
  end
  fmt(a)
end

function get_fmt2(a)
  T = typeof(a)
  S = supertype(T)
  # println("Ta, Sa = $T, $S")
  if S in [Integer Signed Unsigned Bool BigInt] return "d"
  elseif S == AbstractFloat return "f"
  elseif S == AbstractString return "s"
  else return "o"
  end
end

trials = [1 1.0 "Foo" Inf]

println("FMT 1")
for a in trials
  Ta = typeof(a)
  Sa = supertype(Ta)
  println("a, Ta, Sa = $a, $Ta, $Sa")
  println("fmt a = ", get_fmt1(a))
end

println("FMT 2")
for a in trials
  Ta = typeof(a)
  Sa = supertype(Ta)
  println("a, Ta, Sa = $a, $Ta, $Sa")
  println("fmt a = ", get_fmt2(a))
end

```

---

<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:** [January 1, 2017, 9:54am UTC](https://discourse.julialang.org/t/match-type/1232/2 "2017-01-01T09:54:35Z")

</div>

It seems that `@match` handles types not as values, and expressions like

```julia
julia> macroexpand(:(@match S begin
                      AbstractFloat => "f"
                      Integer => "d"
                      AbstractString => "s"
                      _ => "s"
        end))
quote # REPL[53], line 2:
    "f"
end

```

always return the first match. You may want open an issue on Github for the library, to see if this is intended or a bug.

In the meantime, you can work around the problem with

```julia
function type_letter(S)
    @match S begin
        _::Type{Integer} || _::Type{Signed} || _::Type{Unsigned} ||
            _::Type{Bool} || _::Type{BigInt} => "d"
        _::Type{AbstractFloat} => "f"
        _::Type{AbstractString} => "s"
        _ => "s"
    end
end

```

which works as

```julia
julia> [type_letter(supertype(typeof(x))) for x in [1 1.0 "Foo" Inf]]
1×4 Array{String,2}:
 "d" "f" "s" "f"

```

Finally, while your actual use case may differ from the MWE, I am not sure that pattern matching is the best way to approach this.

---

<div class="post-metadata">

**Author:** ![stustd](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stustd/32/21430_2.png) [@stustd](https://discourse.julialang.org/u/stustd)\
**Post date:** [January 3, 2017, 11:00am UTC](https://discourse.julialang.org/t/match-type/1232/3 "2017-01-03T11:00:15Z")

</div>

@Tamas_Papp The “Julia proper way” would be to dispatch `type_letter(S)` on `typeof(S)` (…you notice I’m coming from the Python world…), the match behavior still seems problematic to me – I have posted an issue to the Match.jl github repos.

---

<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:** [January 3, 2017, 11:12am UTC](https://discourse.julialang.org/t/match-type/1232/4 "2017-01-03T11:12:32Z")

</div>

I think that `type_letter` dispatches on a type, see the example below it. Depending on how you plan to extend this, consider something like

```julia
type_letter{T <: Integer}(::Type{T}) = "d"
type_letter(::Type{AbstractFloat}) = "f"
type_letter(::Type{AbstractString}) = "s"
type_letter(_) = "s" # fallback

get_fmt{T}(a::T) = type_letter(supertype(T))

```

Also, depending on your use case, consider

```julia
get_fmt{T <: AbstractFloat}(x::T) = "f"
get_fmt{T <: Integer}(x::T) = "d"
get_fmt{T <: AbstractString}(x::T) = "s"
get_fmt(x) = "s" # fallback

get_fmt.([1 1.0 "Foo" Inf])

```

---

<div class="post-metadata">

**Author:** ![stustd](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stustd/32/21430_2.png) [@stustd](https://discourse.julialang.org/u/stustd)\
**Post date:** [January 5, 2017, 8:28am UTC](https://discourse.julialang.org/t/match-type/1232/5 "2017-01-05T08:28:02Z")

</div>

@Tamas_Papp The true julian/dispatch (very un-pythonic/test) way. Thanks.
