https://github.com/impworks/matcher
Pattern matching in C#
https://github.com/impworks/matcher
Last synced: 3 days ago
JSON representation
Pattern matching in C#
- Host: GitHub
- URL: https://github.com/impworks/matcher
- Owner: impworks
- License: mit
- Created: 2019-03-02T09:53:53.000Z (over 7 years ago)
- Default Branch: master
- Last Pushed: 2019-06-03T14:30:24.000Z (about 7 years ago)
- Last Synced: 2026-04-25T20:11:08.516Z (2 months ago)
- Language: C#
- Size: 43.9 KB
- Stars: 2
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# Matcher
  [](https://www.nuget.org/packages/Impworks.Matcher/) 
A proof-of-concept library for strongly-typed pattern matching in C#.
### Basic syntax
```csharp
var result = Match.Value(3)
.AndReturn()
.With(ctx =>
{
ctx.Value(1, "one");
ctx.Value(2, "two");
ctx.Value(3, "three");
ctx.Default(x => $"just {x}");
});
```
### Supported stuff
Array destructuring (up to 10 elements):
```csharp
Match.Value(new [] { 1, 2, 3 })
.AndReturn()
.With(ctx =>
{
ctx.Array(() => "empty array");
ctx.Array(a => $"just {a}");
ctx.Array((a, b) => $"{a} and {b}");
ctx.Array((a, b, c) => $"{a}, {b}, and {c}");
ctx.Default(x => $"array with {x.Length} values");
});
```
Array with a last argument as "rest":
```csharp
Match.Value(new [] { 1, 2, 3 })
.AndReturn()
.With(ctx =>
{
ctx.ArrayRest((a, rest) => $"{a} and {rest.Length} more"); // 1 and 2 more
});
```
Sequences (`IEnumerable`) are also supported similar to arrays with the `Seq` and `SeqRest` methods.
Tuple deconstructing (supports `ValueTuple` as well):
```csharp
Match.Value(Tuple.Create(1, 2, 3))
.AndReturn()
.With(ctx =>
{
ctx.Tuple((a, b, c) => a + b + c); // equals 6
});
```
Nullable value unpacking:
```csharp
Match.Value((int?)10)
.AndReturn()
.With(ctx =>
{
ctx.Option(i => $"Value is {i}"); // value is 10
});
```
Type checking:
```csharp
Match.Value(new Child())
.AndReturn()
.With(ctx =>
{
ctx.OfType().Is(x => true); // true
ctx.OfType().Is(x => true); // true
ctx.OfType().IsExactly(x => true); // true
ctx.OfType().IsExactly(x => true); // false
});
```
Arbitrary nested patterns:
```csharp
Match.Value(Tuple.Create(1, true, new[] { 1, 2, 3 }))
.AndReturn()
.With(ctx =>
{
ctx.Pattern(p =>
p.Tuple(
1,
p.Var("b").OfType(),
p.Array(
1,
p.Var("a"),
p.Any()
)
)
)
.Map((a, b) => $"{a} and {b}"); // 2 and True
});
```
Regex matches:
```csharp
Match.Value("code is 123")
.AndReturn()
.With(ctx =>
{
ctx.Regex("[0-9]+", v => int.Parse(v)); // 123
});
```
When guards (similarly supported for all other constructs):
```csharp
Match.Value(new [] { 1, 2, 3 })
.AndReturn()
.With(ctx =>
{
ctx.Array((a, b, c) => Option.When(a > b && b > c, "decreasing"));
ctx.Array((a, b, c) => Option.When(c > b && b > a, "increasing")); // this
});
```
### Known limitations
* Arbitrary patterns do not allow static type checking and require explicit type annotations.