Skip to content

Instantly share code, notes, and snippets.

@rbiggs
Created June 18, 2019 12:36
Show Gist options
  • Select an option

  • Save rbiggs/1fe3e3b5c68c08d4b78351dfc26c1f15 to your computer and use it in GitHub Desktop.

Select an option

Save rbiggs/1fe3e3b5c68c08d4b78351dfc26c1f15 to your computer and use it in GitHub Desktop.
A function to create tagged unions.
const hasOwnProperty = Object.prototype.hasOwnProperty
/**
* Create a union of string tags.
* @param {string[]} types
*/
function createUnion(types) {
const variants = Object.create(null)
let checkTag = x => x && x.type
const matcher = (handlers, catchAll) => {
return (tag, context) => {
const tagType = checkTag(tag)
const match = hasOwnProperty.call(handlers, tagType) && handlers[tagType]
return match ? match(tag.data, context) : catchAll(context)
}
}
function match(tag, handlers, catchAll) {
return matcher(handlers, catchAll)(tag)
}
let idx = 0
while (idx < types.length) {
const type = types[idx]
variants[type] = data => ({ type, data })
idx++
}
return { variants, match }
}
/**
* Create a union of types for matching up with functions.
* @param {...string} types
*/
export function union(...types) {
const { variants, match } = createUnion(types)
variants.match = match
return variants
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment