pattern.cr
pattern.cr
Structural pattern matching proof-of-concept library
Usage
Due to syntax restrictions, macro arguments must be valid Crystal expressions and cannot declare new variables, and features like splats in container literals are not supported (but see crystal-lang/crystal#3718). The following conventions are applied in this library:
exp ~>? pat
becomesPattern.matches?(exp, pat)
. Flow typing will not work properly because the bound variables inpat
must be declared prior to this point; usePattern.try_match(exp, pat)
in those cases instead.exp ~> pat
becomesPattern.match!(exp, pat)
. Flow typing works here due to the exception thrown in the failing branch.*x
in array patterns are replaced with__splat(x)
. The__splat
doesn't need to be an existing method.**x
in hash patterns are replaced with__double_splat => x
. Note thatNamedTuple
patterns cannot have a double splat in this way.
Refer to the same examples in SPEC.md
to see how compiler support for structural pattern matching would look like. See also the known limitations.
# Before
ary = [1, 2, 3, 4, 5, 6, 7]
if ary.size >= 2
a, b = ary
rest = ary[2..]
else
raise "not enough elements"
end
# After
require "pattern"
a, b, rest = nil, nil, nil
Pattern.match! [1, 2, 3, 4, 5, 6, 7], [a, b, __splat(rest)]
# Before
if ary.size == 3
first, x, y = ary
end
if first.is_a?(Circle) && x.is_a?(Int32) && y.is_a?(Int32)
first.move_to(x, y)
end
# After
require "pattern"
first = nil
x = nil
y = nil
Pattern.try_match(ary, {first = Circle, x = Int32, y = Int32}) do
first.move_to(x, y)
end
# Before
anniversary = events.find do |ev|
ev.has_key?("start") && ev["start"].in?("2020-01-01".."2020-12-31") &&
ev.has_key?("id") && ev["id"] =~ /^ANNIV.*/
end["start"]
events.select! &.[]?("start").== anniversary
# After
require "pattern"
anniversary = nil
Pattern.match!(events, {__splat(_), {
"start" => anniversary = "2020-01-01".."2020-12-31",
"id" => /^ANNIV.*/,
}, __splat(_)})
events.select! do |ev|
Pattern.matches?(ev, {"start" => __pin(anniversary)})
end
Installation
-
Add the dependency to your
shard.yml
:dependencies: pattern: github: HertzDevil/pattern.cr
-
Run
shards install
Contributing
- Fork it (https://github.com/HertzDevil/pattern.cr/fork)
- Create your feature branch (
git checkout -b my-new-feature
) - Commit your changes (
git commit -am 'Add some feature'
) - Push to the branch (
git push origin my-new-feature
) - Create a new Pull Request
Contributors
- Quinton Miller - creator and maintainer
Repository
pattern.cr
Owner
Statistic
- 7
- 0
- 0
- 0
- 0
- over 3 years ago
- February 27, 2021
License
MIT License
Links
Synced at
Thu, 21 Nov 2024 21:17:11 GMT
Languages