Skip to content

Instantly share code, notes, and snippets.

@mauroc8
Created September 10, 2020 04:30
Show Gist options
  • Save mauroc8/540e30e5fe71f1a8a2eaf0b94cba33dd to your computer and use it in GitHub Desktop.
Save mauroc8/540e30e5fe71f1a8a2eaf0b94cba33dd to your computer and use it in GitHub Desktop.
/* Implementing a Maybe type to learn about typescript.
Maybe API: https://package.elm-lang.org/packages/elm/core/latest/Maybe
The first approach is just trying to copy the exact same functions you'd have in a functional language:
*/
type Maybe<T> =
| { tag: 'Just'; value: T }
| { tag: 'Nothing' }
function withDefault<T>(value: T, maybe: Maybe<T>): T {
if (maybe.tag == 'Just')
return maybe.value
else
return value
}
function map<A, B>(mapFn: (a: A) => B, maybe: Maybe<A>): Maybe<B> {
if (maybe.tag == 'Just')
return { tag: 'Just', value: mapFn(maybe.value) }
else
return maybe
}
function andThen<A, B>(bindFn: (a: A) => Maybe<B>, maybe: Maybe<A>): Maybe<B> {
if (maybe.tag == 'Just')
return bindFn(maybe.value)
else
return maybe
}
/* This second approach tries to be more idiomatic, allowing chained calls and adding a `caseOf` helper method.
*/
interface Maybe<A> {
withDefault: (value: A) => A
map: <B>(func: (a: A) => B) => Maybe<B>
andThen: <B>(func: (a: A) => Maybe<B>) => Maybe<B>
caseOf: <B>(just: (a: A) => B, nothing: () => B) => B
}
class Just<A> implements Maybe<A> {
value: A
constructor(value: A) {
this.value = value
}
withDefault(_: A): A {
return this.value
}
map<B>(func: (a: A) => B): Maybe<B> {
return new Just(func(this.value))
}
andThen<B>(func: (a: A) => Maybe<B>): Maybe<B> {
return func(this.value)
}
caseOf<B>(just: (a: A) => B, _: () => B): B {
return just(this.value)
}
}
class Nothing<A> implements Maybe<A> {
constructor() {}
withDefault(value: A): A {
return value
}
map<B>(_: (a: A) => B): Maybe<B> {
return new Nothing()
}
andThen<B>(_: (a: A) => Maybe<B>): Maybe<B> {
return new Nothing()
}
caseOf<B>(_: (a: A) => B, nothing: () => B): B {
return nothing()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment