0.0.4 β€’ Published 3 years ago

pattern-match-ts v0.0.4

Weekly downloads
-
License
MIT
Repository
-
Last release
3 years ago

Index



Installation

yarn

yarn add pattern-matching-ts

npm

npm install --save pattern-matching-ts

Usage

MatchW

Option MatchW

import * as M from 'pattern-matching-ts/lib/match'
import { pipe } from 'fp-ts/lib/function'
import * as O from 'fp-ts/lib/Option'

const optionMatching = (o: unknown) =>
  pipe(
    o,
    M.matchW('_tag')({
      Some: ({ value }) => 'Something: ' + value,
      None: () => 'Nothing',
      _: () => 'Default'
    })
  )

assert.deepStrictEqual(optionMatching(O.some('data')), 'Something: data')
assert.deepStrictEqual(optionMatching(O.none), 'Nothing')
assert.deepStrictEqual(optionMatching((undefined as unknown) as O.None), 'Default')

Either MatchW

import * as M from 'pattern-matching-ts/lib/match'
import { pipe } from 'fp-ts/lib/function'
import * as E from 'fp-ts/lib/Either'

type RGB = Record<'r' | 'g' | 'b', number>
const either = (maybeRgb: E.Either<string, RGB>) =>
  pipe(
    maybeRgb,
    M.matchW('_tag')({
      Left: ({ left }) => 'Error: ' + left,
      Right: ({ right: { r, g, b } }) => `Red: ${r} | Green: ${g} | Blue: ${b}`
    })
  )

assert.deepStrictEqual(either(E.right({ r: 255, g: 255, b: 0 })), 'Red: 255 | Green: 255 | Blue: 0')

Default MatchW

import * as M from 'pattern-matching-ts/lib/match'
import { pipe } from 'fp-ts/lib/function'

interface ServerResponse<Code extends string | number> {
  readonly code: Code
}

interface Response<Body> {
  readonly response: {
    readonly body: Body
  }
}

interface Success extends ServerResponse<200>, Response<ReadonlyArray<string>> {}

interface NotFoundError extends ServerResponse<404> {}

interface ServerError extends ServerResponse<500> {
  readonly detail: string
}

type Responses = Success | NotFoundError | ServerError

const matchResponse = (response: Responses) =>
  pipe(
    response,
    M.matchW('code')({
      500: ({ detail }) => ({ message: 'Internal server error', detail }),
      404: () => ({ message: 'The page cannot be found!' }),
      200: ({ response }) => response.body,
      _: () => 'Unexpected response'
    })
  )

assert.deepStrictEqual(either(E.right({ r: 255, g: 255, b: 0 })), 'Red: 255 | Green: 255 | Blue: 0')
assert.deepStrictEqual(matchResponse({ code: 200, response: { body: ['data'] } }), ['data'])
assert.deepStrictEqual(matchResponse({ code: 500, detail: 'Cannot connect to the database' }), {
  message: 'Internal server error',
  detail: 'Cannot connect to the database'
})
assert.deepStrictEqual(matchResponse({ code: 404 }), { message: 'The page cannot be found!' })

Match

Option Match

import * as M from 'pattern-matching-ts/lib/match'
import * as O from 'fp-ts/lib/Option'

const optionMatching = M.match<O.Option<string>, string>({
  Some: (x) => `Something: ${x.value}`,
  None: () => 'Nothing'
})

assert.deepStrictEqual(optionMatching(O.some('data')), 'Something: data')
assert.deepStrictEqual(optionMatching(O.none), 'Nothing')

Default Match

import * as M from 'pattern-matching-ts/lib/match'

interface ChangeColor<T = number> {
  readonly _tag: 'ChangeColor'
  readonly value: {
    readonly r: T
    readonly g: T
    readonly b: T
  }
}
interface Move<T = number> {
  readonly _tag: 'Move'
  readonly value: {
    readonly x: T
    readonly y: T
  }
}
interface Write {
  readonly _tag: 'Write'
  readonly value: {
    readonly text: string
  }
}

type Cases = ChangeColor<number> | Move | Write
const matchMessage = M.match<Cases, string>({
  ChangeColor: ({ value: { r, g, b } }) => `Change the color to Red: ${r} | Green: ${g} | Blue: ${b}`,
  Move: ({ value: { x, y } }) => `Move in the x direction: ${x} and in the y direction: ${y}`,
  Write: ({ value: { text } }) => `Text message: ${text}`,
  _: () => 'Default message'
})

const ChangeColor = ({ r, g, b }: ChangeColor<number>['value']): ChangeColor<number> => ({
  _tag: 'ChangeColor',
  value: { r, g, b }
})

const Move = ({ x, y }: Move['value']): Move => ({
  _tag: 'Move',
  value: { x, y }
})

const Write = ({ text }: Write['value']): Write => ({
  _tag: 'Write',
  value: { text }
})

assert.deepStrictEqual(
  matchMessage(Move({ x: 500, y: 100 })),
  'Move in the x direction: 500 and in the y direction: 100'
)

assert.deepStrictEqual(
  matchMessage(ChangeColor({ r: 12, g: 20, b: 30 })),
  'Change the color to Red: 12 | Green: 20 | Blue: 30'
)

assert.deepStrictEqual(matchMessage(Write({ text: 'my message' })), 'Text message: my message')

Blog posts that introduces the API.

πŸ‘‰ Pattern Matching in Typescript

πŸ‘‰ Pipeable Pattern Matching in Typescript

MIT