Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This PR is not intended to replace Qo. It is intended to provide better abstraction for pattern matching.
Pattern matcher is a combination of partial functions wrapped into nice DSL. Every partial function
defined on domain described with guards:
It uses
#===
method under the hood, so you can pass:4
,"Foobar"
, etc.#to_proc
method.m.case(Qo[name: 'John']) { .... }
Partial functions may be combined with each other:
To create custom pattern match use
Fear.match
method andcase
builder to definebranches. For instance this matcher applies different functions to Integers and Strings
if you pass something other than Integer or string, it will raise
Fear::MatchError
error.To avoid raising
MatchError
, you can useelse
method. It defines a branch matchingon any value.
You can use anything as a guardian if it responds to
#===
method:If you pass a Symbol, it will be converted to proc using
#to_proc
methodIt's also possible to pass several guardians. All should match to pass
It's also possible to create matcher and use it several times:
Since matcher is just a syntactic sugar for partial functions, you can combine matchers with partial
functions and each other.
More examples
Factorial using pattern matching
Fibonacci number
Binary tree set implemented using pattern matching https://gist.github.com/bolshakov/3c51bbf7be95066d55d6d1ac8c605a1d
Monads pattern matching
You can use
Option#match
,Either#match
, andTry#match
method. It performs matching notonly on container itself, but on enclosed value as well.
Pattern match against an
Option
pattern match on enclosed value
it raises
Fear::MatchError
error if nothing matched. To avoid exception, you can pass#else
branchPattern matching works the similar way for
Either
andTry
monads.In sake of performance, you may want to generate pattern matching function and reuse it multiple times:
Benchmarks
Short story long, it is slower then just Procs and Dry::Matcher, but provides reacher API for combination. If you generate matcher in advance and save it into constant, you'll gain significant performance boost (execution 4 times faster than construction)
See Rakefile
Recursive factorial implemented using Proc, Fear, and Qo
Option matcher