RelationalAI-oss / Rematch.jl

Pattern matching
Other
52 stars 6 forks source link

Rematch

Build Status

Pattern matching.

Rematch.jl provides a syntax sugar for matching julia values against syntactic patterns. The @match macro expands a pattern-matching syntax into a series of if-elses that check the types and structure of the provided value, allowing you to more simply write checks that describe your intent.

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

Usage

Assignment Syntax

@match pattern = value

If value matches pattern, binds variables and returns value. Otherwise, throws MatchFailure.

After evaluation, any variable names used within pattern will be bound as new variables in the enclosing scope. For example:

julia> @match Foo(x,2) = Foo(1,2)
Foo(1,2)

julia> x
1

Case Syntax

@match value begin
    pattern1 => result1
    pattern2 => result2
    ...
end

Returns result for the first matching pattern. If there are no matching patterns, throws MatchFailure.

Note that unlike the assignment syntax, this does not create any variable bindings outside the match macro.

Patterns

Patterns can be nested arbitrarily.

Repeated variables only match if they are equal (==). For example (x,x) matches (1,1) but not (1,2).

Differences from Match.jl

This package was branched from the original Match.jl. It now differs in several ways: