Created
September 10, 2020 04:30
-
-
Save mauroc8/540e30e5fe71f1a8a2eaf0b94cba33dd to your computer and use it in GitHub Desktop.
This file contains 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
/* 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