Skip to content

Instantly share code, notes, and snippets.

@roblafeve
Last active January 29, 2019 15:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save roblafeve/4627b412c94f20d9980a8266f0cbe342 to your computer and use it in GitHub Desktop.
Save roblafeve/4627b412c94f20d9980a8266f0cbe342 to your computer and use it in GitHub Desktop.
Modeling the Maybe monad in TypeScript
/**
* Tag
* These are used to create the Tagged Union
**/
const enum Tag {
None = "None",
Some = "Some"
}
/**
* MEMBERS
* None and Some are Maybe Members
**/
interface None { tag: Tag.None }
interface Some<A> { tag: Tag.Some, data: A }
/**
* MAYBE
* Maybe is the Union of None and Some.
* It is parameterized by a generic type.
**/
type Maybe<A> = None | Some<A>
/**
* Maybe Constructors
* None is constant while Some is parameterized (function)
**/
const None: None = { tag: Tag.None }
const Some = <A>(x: A): Some<A> => ({ tag: Tag.Some, data: x })
/**
* USEAGE EXAMPLES
* Below are some examples of how to use Maybe
**/
const either = <A>(x: Maybe<A>, y: A): A => {
switch (x.tag) {
case Tag.Some:
return x.data
case Tag.None:
return y
default:
return assertNever(x, y)
}
}
const assertNever = <A>(x: never, y: A) => y
const thing = either(Some("hi"), "bye")
interface User {
name: string
}
const head = <A>(xs: A[]): Maybe<A> => xs[0] === undefined ? None : Some(xs[0])
const users: User[] = []
const firstUser = head(users)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment