Last active
January 29, 2019 15:38
-
-
Save roblafeve/4627b412c94f20d9980a8266f0cbe342 to your computer and use it in GitHub Desktop.
Modeling the Maybe monad in TypeScript
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* 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