Options
All
  • Public
  • Public/Protected
  • All
Menu

Module "@tpoisseau/pattern-matching"

Install

npm install @tpoisseau/pattern-matching
npm install 'https://github.com/tpoisseau/js-pattern-matching#1.0.3'

Use

import pattern, {PatternMatching} from '@tpoisseau/pattern-matching';
import * as comparators from '@tpoisseau/pattern-matching/comparators';
import * as evaluators from '@tpoisseau/pattern-matching/evaluators';

Index

Classes

Interfaces

Functions

Functions

pattern

  • Provide a pattern-matching like syntax with functional fluent chainable api

    Think pattern as switch keyword and match as case keyword but without need to break the switch-case expression

    You could set a a default evaluator (take pattern value as argument) return what you want

    If a ProxyPatternMatching or PatternMatching is executed with no matching value. It will return the pattern value by default. Use .default(evaluator) for override

    example
    import pattern from '@tpoisseau/pattern-matching';
    
    const value = pattern('foo')
     .match('bar', Symbol('bar'))
     .match('foo', Symbol('foo'))
     .exec(); // value Symbol('foo')

    https://github.com/tc39/proposal-pattern-matching#motivating-examples

    Matching fetch() response

    import pattern from '@tpoisseau/pattern-matching'
    import {objectStrictLike} from '@tpoisseau/pattern-matching/comparators'
    import {throwNewError} from '@tpoisseau/pattern-matching/evaluators'
    
    pattern(await fetch(jsonService))
     .match(objectStrictLike({status: 200}), ({headers: {'Content-Length': l}}) => console.log(l))
     .match({status: 404}, () => console.log('JSON not found'))
     .match(({status}) => status >= 404, throwNewError(RequestError))
     .exec()

    Handling Reducer

    import pattern from '@tpoisseau/pattern-matching'
    import {objectStrictLike} from '@tpoisseau/pattern-matching/comparators'
    
    function todoApp(state=initialState, action) {
        return pattern(action)
         .match({type: 'set-visibility-filter'}, ({filter: visFilter}) => ({...state, visFilter}))
         .match(objectStrictLike({type: 'add-todo'}), ({text}) => ({...state, todos: [...state.todos, {text}]})
         .match({type: 'toggle-todo'}, ({index}) => ({
             ...state,
             todos: state.todos.map(({...item, done}, idx) => ({...item, done: idx === index ? !done : done})
         })
         .default(state)()
    }

    When firts param of match is an object use objectStrictLike to generate the predicate.

    mixed in with JSX code for quick props handling

    import pattern from '@tpoisseau/pattern-matching'
    import { haveKeys } from '@tpoisseau/pattern-matching/comparators'
    
    <Fetch url={API_URL}>{
        props => pattern(props)
         .match(haveKeys('loading'), <Loading />)
         .match(haveKeys('error'), ({error}) => <Error error={error} />)
         .match(haveKeys('data'), ({data}) => <Page data={data} />)()
    }</Fetch>

    When the second parameter of match (evaluator) is not a function will use the returnValue factory evaluator So .match(haveKeys('loading'), <Loading />) is like using .match(haveKeys('loading'), () => <Loading />)

    General structural duck-typing on an API for vector-likes.

    import pattern from '@tpoisseau/pattern-matching'
    import { haveKeys } from '@tpoisseau/pattern-matching/comparators'
    
    const getLength = vector => pattern(vector)
     .match(haveKeys('x', 'y', 'z'), ({x, y, z}) => Math.sqrt(x**2 + y**2 + z**2))
     .match(haveKeys('x', 'y'), ({x, y}) => Math.sqrt(x**2 + y**2))
     .match(haveKeys('x'), ({x}) => Math.sqrt(x**2))
     .match(Array.isArray, vector => Math.sqrt.apply(Math, vector.map(v => v**2)))
     .default(NaN)()

    Type parameters

    • EV

    • PV

    • R

    Parameters

    • value: PV

    Returns ProxyPatternMatching<EV, PV, R>

Generated using TypeDoc