Skip to content

Instantly share code, notes, and snippets.

@icorbrey
Last active October 18, 2022 20:51
Show Gist options
  • Save icorbrey/f67dc728c522a614e3d38e28adca7635 to your computer and use it in GitHub Desktop.
Save icorbrey/f67dc728c522a614e3d38e28adca7635 to your computer and use it in GitHub Desktop.
export type Option<T> = {
unwrap: (message?: string) => T
match: <R>(matchers: OptionMatchers<T, R>) => R
}
type OptionMatchers<T, R> = {
onSome: (value: T) => R
onNone: () => R
}
type OptionValue<T> =
| Some<T>
| None
type Some<T> = {
__isSome: true
value: T
}
type None = {
__isSome: false
}
const some = <T>(value: T) => toOption({
__isSome: true,
value,
})
const none = () => toOption({
__isSome: false,
})
const toOption = <T>(option: OptionValue<T>): Option<T> => {
const unwrap = (message?: string): T => {
if (!message) {
console.log('Either provide a failure message to <option>.unwrap or use <option>.match');
}
if (option.__isSome) {
return option.value;
}
throw new Error(message ?? 'Option was not Some');
}
const match = <R>(matchers: OptionMatchers<T, R>): R =>
option.__isSome
? matchers.onSome(option.value)
: matchers.onNone();
return ({
unwrap,
match,
})
}
export const object = Object.freeze({
some,
none,
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment