Pattern matching.
julia> using Rematch
julia> struct Foo
x::Int64
y::String
end
julia> f(x) = @match x begin
_::String => :string
[a,a,a] => (:all_the_same, a)
[a,bs...,c] => (:at_least_2, a, bs, c)
Foo(x, "foo") where x > 1 => :foo
end
f (generic function with 1 method)
julia> f("foo")
:string
julia> f([1,1,1])
(:all_the_same, 1)
julia> f([1,1])
(:at_least_2, 1, Int64[], 1)
julia> f([1,2,3,4])
(:at_least_2, 1, [2, 3], 4)
julia> f([1])
ERROR: Rematch.MatchFailure([1])
Stacktrace:
[1] macro expansion at /home/jamie/.julia/v0.6/Rematch/src/Rematch.jl:173 [inlined]
[2] f(::Array{Int64,1}) at ./REPL[3]:1
julia> f(Foo(2, "foo"))
:foo
julia> f(Foo(0, "foo"))
ERROR: Rematch.MatchFailure(Foo(0, "foo"))
Stacktrace:
[1] macro expansion at /home/jamie/.julia/v0.6/Rematch/src/Rematch.jl:173 [inlined]
[2] f(::Foo) at ./REPL[13]:1
julia> f(Foo(2, "not a foo"))
ERROR: Rematch.MatchFailure(Foo(2, "not a foo"))
Stacktrace:
[1] macro expansion at /home/jamie/.julia/v0.6/Rematch/src/Rematch.jl:173 [inlined]
[2] f(::Foo) at ./REPL[13]:1@match pattern = valueIf value matches pattern, binds variables and returns value. Otherwise, throws MatchFailure.
@match value begin
pattern1 => result1
pattern2 => result2
...
endReturns result for the first matching pattern. If there are no matching patterns, throws MatchFailure.
_matches anythingfoomatches anything, binds value tofooFoo(x,y,z)matches structs of typeFoowith fields matchingx,y,z[x,y,z]matchesAbstractArrays with 3 entries matchingx,y,z(x,y,z)matchesTuples with 3 entries matchingx,y,z[x,y...,z]matchesAbstractArrays with at least 2 entries, wherexmatches the first entry,zmatches the last entry andymatches the remaining entries.(x,y...,z)matchesTuples with at least 2 entries, wherexmatches the first entry,zmatches the last entry andymatches the remaining entries._::Tmatches any subtype (isa) of Tx || ymatches values which match eitherxory(only variables which exist in both branches will be bound)x && ymatches values which match bothxandyx where conditionmatches only ifconditionis true (conditionmay use any variables that occur earlier in the pattern eg(x, y, z where x + y > z))- Anything else is treated as a constant and tested for equality
Patterns can be nested arbitrarily.
Repeated variables only match if they are == eg (x,x) matches (1,1) but not (1,2).
Differences from Match.jl
- If no branches are matched, throws
MatchFailureinstead of returning nothing. - Matching against a struct with the wrong number of fields produces an error instead of silently failing.
- Repeated variables are handled correctly ie
@match (1,2) begin (x,x) => :ok endfails. - The syntax for guards is
x where x > 1instead ofx, if x > 1 endand can occur anywhere in a pattern. - No support (yet) for matching
RegexorUnitRange. - No support (yet) for matching against multidimensional arrays - all array patterns use linear indexing.