Pattern matching = switch++

Photo by Parham Moieni on Unsplash

After learning about the exciting, but sadly only Stage 1 proposal for pattern-matching in JavaScript, I felt compelled to write a library that tries to, erm, match it as closely as I could:

import { match, when, …


This content originally appeared on DEV Community and was authored by Conan

Photo by Parham Moieni on Unsplash

After learning about the exciting, but sadly only Stage 1 proposal for pattern-matching in JavaScript, I felt compelled to write a library that tries to, erm, match it as closely as I could:

import { match, when, otherwise } from 'match-iz'

match(haystack)(
  when(needle)(true),
  when(thread)(false),
  otherwise('bale')
)

Essentially, pattern-matching is if/then and switch/case with a little more declarative cowbell. ? ?

We can probe into an object:

const todosReducer = (state, action) =>
  match(action)(
    when({ type: 'set-vis-filter' })
      (({ visFilter }) => ({
        ...state,
        visFilter
      })),

    when({ type: 'add-todo' })
      (({ text }) => ({
        ...state,
        todos: [...state.todos, { text, completed: false }]
      })),

    otherwise(state)
  )

...test against predicates as well as literals:

const defined = obj => !!obj

function AccountPage(props) {
  return match(props)(
    when({ error: true })(<Error {...props} />),
    when({ loading: true })(<Loading />),
    when({ data: defined })(<Page {...props} />),
    otherwise(<Logout />)
  )
}

...which is handy for dealing with server-responses:

const getJsonLength = async () =>
  match(await fetch('/json'))(
    when({ status: 200 })
      (({ headers: { 'Content-Length': s } = {} }) => {
        return `size is ${s}`
      }),

    when(({ status }) => status >= 500)('Server error!'),
    when({ status: 404 })('JSON not found'),
    when({ status: gte(400) })('Flagrant error!'),

    otherwise("I didn't understand that...")
  )

...and match strings against regular-expressions, passing the result into the handler:

match('1 + 2')(
  when(/(?<left>\d+) \+ (?<right>\d+)/)
    (({ groups: { left, right } }) =>
      add(left, right)
    ),

  when(/(?<left>\d+) \- (?<right>\d+)/)
    (({ groups: { left, right } }) =>
      subtract(left, right)
    ),

  otherwise("I couldn't parse that!")
)
// 3

The only thing we can't have is else instead of otherwise. ?

The full TC39 proposal is more far-reaching because it is inspired by the advanced pattern-matching features offered by functional languages with mature implementations.

Still, while we wait for the language feature I think match-iz (along with many similar libraries) is a nice tool for constructing some of the conditional logic we use in our JavaScript.

It's not a substitute for well named intermediate variables of course, but I hope you can see its utility.


This content originally appeared on DEV Community and was authored by Conan


Print Share Comment Cite Upload Translate Updates
APA

Conan | Sciencx (2021-08-18T21:41:59+00:00) Pattern matching = switch++. Retrieved from https://www.scien.cx/2021/08/18/pattern-matching-switch/

MLA
" » Pattern matching = switch++." Conan | Sciencx - Wednesday August 18, 2021, https://www.scien.cx/2021/08/18/pattern-matching-switch/
HARVARD
Conan | Sciencx Wednesday August 18, 2021 » Pattern matching = switch++., viewed ,<https://www.scien.cx/2021/08/18/pattern-matching-switch/>
VANCOUVER
Conan | Sciencx - » Pattern matching = switch++. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2021/08/18/pattern-matching-switch/
CHICAGO
" » Pattern matching = switch++." Conan | Sciencx - Accessed . https://www.scien.cx/2021/08/18/pattern-matching-switch/
IEEE
" » Pattern matching = switch++." Conan | Sciencx [Online]. Available: https://www.scien.cx/2021/08/18/pattern-matching-switch/. [Accessed: ]
rf:citation
» Pattern matching = switch++ | Conan | Sciencx | https://www.scien.cx/2021/08/18/pattern-matching-switch/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.