• This repository has been archived on 16/Jul/2024
  • Stars
    star
    180
  • Rank 213,097 (Top 5 %)
  • Language
    TypeScript
  • License
    MIT License
  • Created almost 2 years ago
  • Updated about 1 year ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Functional pattern matching with the full power of TypeScript

Functional pattern matching with the full power of Typescript.

Getting started

To install from npm:

npm install @effect/match

Once you have installed the library, you can import the necessary types and functions from the @effect/match module.

import * as Match from "@effect/match"

Defining a Matcher

To define a Matcher from a given type, you can use the type constructor function.

You can then use the when, not & tag combinators to specify the patterns to match against.

For example:

import * as Match from "@effect/match"
import { pipe } from "@effect/data/Function"

const match = pipe(
  Match.type<{ a: number } | { b: string }>(),
  Match.when({ a: Match.number }, (_) => _.a),
  Match.when({ b: Match.string }, (_) => _.b),
  Match.exhaustive,
)

console.log(match({ a: 0 })) // 0
console.log(match({ b: "hello" })) // "hello"

You can also create a Matcher from a value using the value constructor function.

For example:

import * as Match from "@effect/match"
import { pipe } from "@effect/data/Function"

const result = pipe(
  Match.value({ name: "John", age: 30 }),
  Match.when(
    { name: "John" },
    (user) => `${user.name} is ${user.age} years old`,
  ),
  Match.orElse(() => "Oh, not John"),
)

console.log(result) // "John is 30 years old"

Types of patterns

Predicates

Values can be tested against arbitrary functions.

import * as Match from "@effect/match"
import { pipe } from "@effect/data/Function"

const match = pipe(
  Match.type<{ age: number }>(),
  Match.when({ age: (age) => age >= 5 }, (user) => `Age: ${user.age}`),
  Match.orElse((user) => `${user.age} is too young`),
)

console.log(match({ age: 5 })) // "Age: 5"
console.log(match({ age: 4 })) // "4 is too young"

not patterns

not lets you match on everything but a specific value.

import * as Match from "@effect/match"
import { pipe } from "@effect/data/Function"

const match = pipe(
  Match.type<string | number>(),
  Match.not("hi", (_) => "a"),
  Match.orElse(() => "b"),
)

console.log(match("hello")) // "a"
console.log(match("hi")) // "b"

tag patterns

Matches against the tag in a Discriminated Union

import * as Match from "@effect/match"
import * as E from "@effect/data/Either"
import { pipe } from "@effect/data/Function"

// type Either<L, R> = { _tag: "Right", right: R } | { _tag: "Left", left: L }
const match = pipe(
  Match.type<E.Either<string, number>>(),
  Match.tag("Right", (_) => _.right),
  Match.tag("Left", (_) => _.left),
  Match.exhaustive,
)

console.log(match(E.right(123))) // 123

Evaluating a Matcher

option

A Matcher that might match a value. Returns an Option.

import * as Match from "@effect/match"
import * as E from "@effect/data/Either"
import { pipe } from "@effect/data/Function"

// type Either<L, R> = { _tag: "Right", right: R } | { _tag: "Left", left: L }
// type Option<T> = { _tag: "Some", value: T } | { _tag: "None" }
const result = pipe(
  Match.value(E.right(0)),
  Match.when({ _tag: "Right" }, (_) => _.right),
  Match.option,
)

console.log(result) // { _tag: "Some", value: 0 }

exhaustive

A Matcher that marks the end of the matching process and checks if all possible matches were made. Returns the match (for Match.value) or the evaluation function (for Match.type).

import * as Match from "@effect/match"
import * as E from "@effect/data/Either"
import { pipe } from "@effect/data/Function"

// type Either<L, R> = { _tag: "Right", right: R } | { _tag: "Left", left: L }
const result = pipe(
  Match.value(E.right(0)),
  Match.when({ _tag: "Right" }, (_) => _.right),
  Match.exhaustive, // TypeError! { _tag: "left", left: never } is not assignable to never
)

orElse

A Matcher that marks the end of the matcher and allows to provide a fallback value if no patterns match. Returns the match (for Match.value) or the evaluation function (for Match.type).

import * as Match from "@effect/match"
import { pipe } from "@effect/data/Function"

const match = pipe(
  Match.type<string | number>(),
  Match.when("hi", (_) => "hello"),
  Match.orElse(() => "I literally do not understand"),
)

console.log(match("hello")) // "I literally do not understand"
console.log(match("hi")) // "hello"

either

A Matcher that might match a value. Returns an Either in the shape of Either<NoMatchResult, MatchResult>.

import * as Match from "@effect/match"
import { pipe } from "@effect/data/Function"

const match = pipe(
  Match.type<string>(),
  Match.when("hi", (_) => "hello"),
  Match.either,
)

// type Either<L, R> = { _tag: "Right", right: R } | { _tag: "Left", left: L }
console.log(match("hi")) // { _tag: "Right", value: "hello" }
console.log(match("shigidigi")) // { _tag: "Left", value: "shigidigi" }

License

The MIT License (MIT)

More Repositories

1

effect

An ecosystem of tools for building production-grade applications in TypeScript.
TypeScript
6,885
star
2

schema

Modeling the schema of data structures as first-class values
TypeScript
498
star
3

data

Custom built data types leveraged by the Effect ecosystem
TypeScript
185
star
4

io

Effect's core runtime, a fiber-based implementation of structured concurrency
TypeScript
122
star
5

website

Source code for Effect's documentation website
MDX
97
star
6

examples

A repository of examples showing how to use Effect
TypeScript
82
star
7

cluster

TypeScript
65
star
8

cli

Rapidly build powerful and composable command-line applications
TypeScript
59
star
9

discord-bot

The Effect Community's custom Discord bot, built with Effect
TypeScript
57
star
10

stream

An implementation of pull-based streams built with Effect
TypeScript
49
star
11

platform

Unified interfaces for common platform-specific services
TypeScript
39
star
12

language-service

TypeScript
35
star
13

typeclass

A collection of re-usable typeclasses for the Effect ecosystem
TypeScript
31
star
14

query

Efficiently pipeline, batch, and cache requests to any data source
TypeScript
30
star
15

rpc

TypeScript
29
star
16

stm

An implementation of software transactional memory built with Effect
TypeScript
27
star
17

docgen

An opinionated documentation generator for Effect projects
TypeScript
26
star
18

vscode-extension

Tools to assist development with the Effect Typescript framework
TypeScript
21
star
19

opentelemetry

OpenTelemetry integration with Effect
TypeScript
15
star
20

eslint-plugin

A set of ESlint and TypeScript rules to work with Effect
TypeScript
15
star
21

printer

An easy to use, extensible pretty-printer for rendering documents
TypeScript
13
star
22

cache

An Effect native cache with a simple and compositional interface
TypeScript
11
star
23

node

TypeScript
11
star
24

process

A simple library for interacting with external processes and command-line programs via Effect-TS (port of zio-process)
TypeScript
10
star
25

express

Wrapper around Express
TypeScript
9
star
26

infra

Infrastructure relevant to the Effect organization
Nix
9
star
27

codemod

Code mod's for the Effect ecosystem
TypeScript
9
star
28

otel

OpenTelemetry integration with Effect
TypeScript
8
star
29

monocle

Optics for your data (port of monocle-ts)
TypeScript
6
star
30

experimental

A repository for experimental Effect libraries
TypeScript
6
star
31

fastify

Fastify integration with Effect
TypeScript
5
star
32

build-utils

Custom utilities used to assist with building and packaging Effect libraries
TypeScript
4
star
33

morphic

Domain Modelling and Structural Derivation (port of morphic-ts)
TypeScript
4
star
34

html

TypeScript
4
star
35

test

TypeScript
4
star
36

remix-plugin

TypeScript
2
star
37

jest

Jest Test Runtime
TypeScript
2
star
38

content

TypeScript
2
star
39

monorepo-testing

TypeScript
1
star
40

.github

Organization-wide configuration for Effect-TS
1
star
41

dtslint

Effect's custom fork of dtslint used to lint TypeScript declaration (.d.ts) files
TypeScript
1
star
42

awesome-effect

1
star
43

sqlite

1
star
44

figlet

An implementation of a FIGlet font parser and renderer built with Effect
TypeScript
1
star
45

babel-plugin

A babel plugin purpose-built for the Effect ecosystem
TypeScript
1
star
46

vite-plugin-react

TypeScript
1
star