You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: README.md
+11-9Lines changed: 11 additions & 9 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -8,9 +8,9 @@ Resulting code will have improved maintainability and better runtime type safety
8
8
9
9
Pattern matching is a fundamental and powerful building block to many functional programming languages like [Haskell](http://learnyouahaskell.com/syntax-in-functions) or [Scala](http://docs.scala-lang.org/tutorials/tour/pattern-matching.html).
10
10
11
-
*TODO: Disclaimer: Language-Level Pattern matchers go further than what we build here… Though its a nice abstraction pattern to improve code maintainability*
11
+
*TODO: Disclaimer: Language-Level Pattern matchers go further than what we build here… Though it's a nice abstraction pattern to improve code maintainability*
12
12
13
-
A *pattern* can contain one or more *cases*. Each *case* describes *behaviour* which has to be applied once the *case* matches.
13
+
A *pattern* can contain one or more *cases*. Each *case* describes *behavior* which has to be applied once the *case* matches.
14
14
15
15
You might think: *"Hey! That sounds like a `switch` statement to me!"*. And you are right indeed:
We can use a `switch` statement to map `number`s to its desired `string` representation.
41
41
42
-
Doing so is straight forward, though we can make out flaws for `matchNumber`:
42
+
Doing so is straightforward, though we can make out flaws for `matchNumber`:
43
43
44
-
1. The *behaviour* for each case is baked into the `matchNumber` function. If you want to map `number`s to, lets say `boolean`s, you have to reimplement the complete `switch` block in another function.
45
-
2. Requirements can be misinterpreted and behaviour for a case gets lost. What about `4`? What if a developer forgets about `default`?
44
+
1. The *behavior* for each case is baked into the `matchNumber` function. If you want to map `number`s too, let's say `boolean`s, you have to reimplement the complete `switch` block in another function.
45
+
2. Requirements can be misinterpreted and behavior for a case gets lost. What about `4`? What if a developer forgets about `default`?
46
46
The possibility of bugs multiplies easily when the `switch` is reimplemented several times as described under point 1.
47
47
48
48
Trying to solve these flaws outlines requirements for an improved solution:
49
49
50
-
1. Separate matching a specific *case* from its *behaviour*
50
+
1. Separate matching a specific *case* from its *behavior*
51
51
2. Make reuse of matcher simple to prevent bugs through duplicated code
52
52
3. Implement matcher once for different types
53
53
54
54
## Separation of Concerns
55
55
56
-
Lets define an interface containing functions for each *case* we want be able to match. This allows to separate behaviour from actual matcher logic later.
56
+
Let's define an interface containing functions for each *case* we want to be able to match. This allows separating behavior from actual matcher logic later.
57
57
58
58
```typescript
59
59
interfaceNumberPattern {
@@ -98,7 +98,7 @@ const match = matchNumber({
98
98
console.log(match(randomNumber()))
99
99
```
100
100
101
-
We clearly separated *case behaviours* from the matcher. That first point can be ticked off. Does it further us from duplicating code and improve maintainability of the matcher?
101
+
We clearly separated *case behaviors* from the matcher. That first point can be ticked off. Does it further duplicating code and improve maintainability of the matcher?
Another tick! Because we have split concerns by introducing `NumberPattern`, changing behavior without reimplementing the underlying matcher logic is straight forward.
114
+
Another tick! Because we have split concerns by introducing `NumberPattern`, changing behavior without reimplementing the underlying matcher logic is straightforward.
This fulfills the last point in our requirement list to implement the matcher once for different types. The final example will probably never make it to production code, though it demonstrates the basic mechanic how a pattern and a corresponding matcher can be implemented in TypeScript.
0 commit comments