Skip to content

Latest commit

 

History

History
330 lines (228 loc) · 10.2 KB

2. Built-in Patterns.md

File metadata and controls

330 lines (228 loc) · 10.2 KB

Built-In Patterns

The library contains built-in patterns contained in the patterns object with shortcuts to create them in the is object.
Below, any instatiated class refers to a class in the patterns object, any functions prefixed with is refers to one in the is object, and any other name refers to one on the library index object.

ID

  • new IDPattern(id)
  • is.id(id)
  • $(id)
  • $.id

Creates a pattern that matches any value and extracts it to id in the extracted object.
If previousExtracted already has a key id, the value from there must be equal via Object.is for the given value for a match.

The $ shortcut allows you to pass in any valid value to use as the key.
If you use the access shortcut (via the proxy, e.g. $.x or $['hi']), some properties are reserved for reflection.

new IDPattern('x')[extractor](1, {})
 { matched: true, extracted: { x: 1 } }

new IDPattern('x')[extractor](1, { x: 2 })
 { matched: false }

new IDPattern('x')[extractor](1, { x: 1 })
 { matched: true, extracted: { x: 1 } }

Ignore

  • new IgnorePattern()
  • is.ignore()
  • _

Creates a pattern that matches any value.
The _ shortcut is an already instantiated IgnorePattern so it can be used immediately.

new IgnorePattern()[extractor](1, {})
 { matched: true, extracted: {} }

Equal

  • new EqualPattern(value)
  • is.equal(value)

Creates a pattern that matches if the given value is equal using Object.is with the value.

new EqualPattern('hello')[extractor]('hello', {})
 { matched: true, extracted: {} }

new EqualPattern('hello')[extractor]('goodbye', {})
 { matched: false }

Multiple

  • new MultiplePattern(...patterns)
  • is.oneOf(...patterns)

Creates a pattern that matches if the given value matches any of the patterns.

new MultiplePattern('hello', 'goodbye')[extractor]('hello', {})
 { matched: true, extracted: {} }

new MultiplePattern('hello', 'goodbye')[extractor]('goodbye', {})
 { matched: true, extracted: {} }

new MultiplePattern('hello', 'goodbye')[extractor]('see ya later', {})
 { matched: false }

Range

  • new RangePattern(lowerBound, upperBound[, exclusive = true])
  • is.inRange(lowerBound, upperBound[, exclusive = true])

Creates a pattern that matches if the given value is within a range.
JavaScript allows this to work with numbers, strings, and bigints.

new RangePattern(0, 100)[extractor](5, {})
 { matched: true, extracted: {} }

new RangePattern(0, 100)[extractor](100, {})
 { matched: false }

new RangePattern(0, 100, false)[extractor](100, {})
 { matched: true, extracted: {} }

Type

  • new TypePattern(type, pattern)
  • is.type(type, pattern)
  • $$(type, pattern)

Creates a pattern that matches if the typeof the given value is equal to type and that pattern also matches.
The extracted object that pattern extracts is used.

The $$ shorcut determines this pattern by whether the first argument is a string.

new TypePattern('string', $.x)[extractor]('hello', {})
 { matched: true, extracted: { x: 'hello' } }

new TypePattern('string', $.x)[extractor](100, {})
 { matched: false }

Instance

  • new InstancePattern(Class, pattern)
  • is.instance(Class, pattern)
  • $$(Class, pattern)

Creates a pattern that matches if the given value is an instanceof Class and that pattern also matches.
The extracted object that pattern extracts is used.

The $$ shorcut determines this pattern if neither TypePattern nor TagPattern was determined.

class X {}
class Y extends X {}
class Z {}

new InstancePattern(X, $.x)[extractor](new X(), {})
 { matched: true, extracted: { x: X {} } }

new InstancePattern(X, $.x)[extractor](new Y(), {})
 { matched: true, extracted: { x: Y {} } }

new InstancePattern(X, $.x)[extractor](new Z(), {})
 { matched: false }

Tag

  • new TagPattern(Class, pattern)
  • is.tag(Class, pattern)
  • $$(Class, pattern)

Creates a pattern that matches if the given value is an instanceof Class and that pattern also matches.
The value that is passed into pattern is the value property on the tagged type instance.
The extracted object that pattern extracts is used.

The $$ shorcut determines this pattern by whether the first argument is a tagged union class.

To learn how tagged unions work, see this section.

const { ValueT, ArrayT } = pat.union('Thing', ['ValueT', 'value'], ['ArrayT', 'array']);

new TagPattern(ValueT, $.x)[extractor](new ValueT(1), {})
 { matched: true, extracted: { x: 1 } }

new TagPattern(ArrayT, $.x)[extractor](new ArrayT(1, 2, 3), {})
 { matched: true, extracted: { x: [1, 2, 3] } }

Preguarded

  • new PreguardedPattern(predicate, pattern)
  • is.preguarded(predicate, pattern)

Creates a pattern that matches if the predicate of the given value is true and that pattern also matches.
The extracted object that pattern extracts is used.

new PreguardedPattern(x => x.length > 2, $.x)[extractor]([1, 2, 3], {})
 { matched: true, extracted: { x: [1, 2, 3] } }

new PreguardedPattern(x => x.length > 2, $.x)[extractor]([1], {})
 { matched: false }

Guarded

  • new GuardedPattern(pattern, predicate)
  • is.guarded(pattern, predicate)

Creates a pattern that matches if the pattern matches and the predicate of the extracted object from pattern is true.
The extracted object that pattern extracts is used.

new GuardedPattern({ x: $.x }, ({ x }) => x.length > 2)[extractor]({ x: [1, 2, 3] }, {})
 { matched: true, extracted: { x: [1, 2, 3] } }

new GuardedPattern({ x: $.x }, ({ x }) => x.length > 2)[extractor]({ x: [1] }, {})
 { matched: false }

Array

  • new ArrayPattern(patterns[, restPattern])
  • is.array(patterns[, restPattern])

Here, patterns must be an array.
It creates a pattern that matches if:

  • The given value is an array.
  • The given value has a length equal to the length of patterns or has a length at least equal to the length of patterns if a restPattern was given.
  • Every pattern in patterns matches the corresponding element in the given value.
  • The restPattern matches the rest of the array if it was given.

The previousExtracted object is updated after every pattern match in patterns.

new ArrayPattern([1, 2, $.x])[extractor]([1, 2, 3], {})
 { matched: true, extracted: { x: 3 } }

new ArrayPattern([1, 2, $.x])[extractor]([1, 2, 3, 4], {})
 { matched: false }

new ArrayPattern([1, 2, $.x], $.rest)[extractor]([1, 2, 3, 4], {})
 { matched: true, extracted: { x: 3, rest: [4] } }

new ArrayPattern([1, $.x, $.x])[extractor]([1, 2, 2], {})
 { matched: true, extracted: { x: 2 } }

new ArrayPattern([1, $.x, $.x])[extractor]([1, 2, 3], {})
 { matched: false }

Object

  • new ObjectPattern(patterns[, restPattern])
  • is.object(patterns[, restPattern])

Here, patterns must be an object.
It creates a pattern that matches if:

  • The given value is an object.
  • Every key in patterns exists in the given value.
  • Every (key, pattern) in patterns matches the corresponding (key, value) in the given value.
  • The restPattern matches the rest of the object (using own property names and symbols) if it was given.

The previousExtracted object is updated after every pattern match in patterns.

new ObjectPattern({ x: $.x })[extractor]({ x: 10, y: 11 }, {})
 { matched: true, extracted: { x: 10 } }

new ObjectPattern({ z: $.z })[extractor]({ x: 10, y: 11 }, {})
 { matched: false }

new ObjectPattern({ x: $.x }, $.rest)[extractor]({ x: 10, y: 11 }, {})
 { matched: true, extracted: { x: 10, rest: { y: 11 } } }

Map

  • new MapPattern(patterns[, restPattern])
  • is.map(patterns[, restPattern])

Here, patterns must be a Map.
It creates a pattern that matches if:

  • The given value is a Map.
  • Every key in patterns exists in the given value.
  • Every (key, pattern) in patterns matches the corresponding (key, value) in the given value.
  • The restPattern matches the rest of the map if it was given.

The previousExtracted object is updated after every pattern match in patterns.

new MapPattern(new Map().set('x', $.x))[extractor](new Map().set('x', 10).set('y', 11), {})
 { matched: true, extracted: { x: 10 } }

new MapPattern(new Map().set('z', $.z))[extractor](new Map().set('x', 10).set('y', 11), {})
 { matched: false }

new MapPattern(new Map().set('x', $.x), $.rest)[extractor](new Map().set('x', 10).set('y', 11), {})
 { matched: true, extracted: { x: 10, rest: { y: 11 } } }

String

  • new StringPattern(string, restPattern)
  • is.string(string, restPattern)

Creates a pattern that matches if the given value starts with string and restPattern matches the rest of the value.
The extracted object that restPattern extracts is used.

new StringPattern('hello', $.rest)[extractor]('hello world', {})
 { rest: 'world' }

View

  • new ViewPattern(fn, pattern)
  • is.view(fn, pattern)

Creates a pattern that matches if fn of the given value matches the pattern.
This is used to map a value into another for another pattern.
The extracted object that pattern extracts is used.

new ViewPattern(a => a[0], $.x)[extractor]([5, 4], {})
 { matched: true, extracted: { x: 5 } }

Bind

  • new BindPattern(pattern, id)
  • is.bind(pattern, id)

Creates a pattern that matches the given value with pattern.
The original given value is then added to the extracted object with key id.
The extracted object must not have a key the same as id, i.e. pattern cannot extract something with the same key as the bind pattern's id.
If previousExtracted already has a key id, the value from there must be equal via Object.is for the given value for a match.

new BindPattern(is.inRange(1, 10), $.x)[extractor](5, {})
 { matched: true, extracted: { x: 5 } }

new BindPattern(is.inRange(1, 10), $.x)[extractor](5, { x: 2 })
 { matched: false }

new BindPattern(is.inRange(1, 10), $.x)[extractor](5, { x: 5 })
 { matched: true, extracted: { x: 5 } }

new BindPattern([$.x], $.x)[extractor]([1], {})
 Error