Last active
September 17, 2019 20:17
-
-
Save fvilante/6ce13329bf307d307a040a63b70fe560 to your computer and use it in GitHub Desktop.
Pattern Match
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
namespace Maybe_ { | |
type Undefined = typeof Undefined | |
const Undefined = Symbol.for("None") // undefined | |
interface Just<T> { | |
readonly type: "Just", | |
readonly val: T | Undefined | |
} | |
interface None<T> { | |
readonly type: "None", | |
readonly val: T | Undefined | |
} | |
export interface Maybe<T> { | |
readonly type: "Maybe" | |
readonly val: Just<T> | None<T> | |
} | |
export const Just = <T>(val: T ): Maybe<T> => | |
({ type: "Maybe", val: { type: "Just", val } }) | |
const None_ = <T>(val: T ): Maybe<T> => | |
({ type: "Maybe", val: { type: "None", val } }) | |
export const None = None_<Undefined>(Undefined) | |
// Teste inferencia implicita deste maybe foi | |
// omitida por motivos de brevidade. mas pode | |
// ser vista aqui: | |
// [link](https://gist.github.com/fvilante/2f53b699794c1ac35e087872e0acac98#file-functional-core-ts-L27) | |
} | |
namespace PatternMatch { | |
import Just = Maybe_.Just | |
import None = Maybe_.None | |
import Maybe = Maybe_.Maybe | |
type InferMaybeType<T> = T extends Maybe<infer U> ? U : never | |
type Maybe_<T> = Maybe<InferMaybeType<T>> // helper for brevity | |
type GetMaybeConstructors<T extends Maybe_<T>> = T['val']['type'] | |
type CallBack<T, U> = (value: T) => U | |
type Match<T extends Maybe_<T>> = { | |
[Constructor in GetMaybeConstructors<T>]: CallBack< InferMaybeType<T>, any > | |
} | |
const match = <T extends Maybe_<T>>(maybe: T, match_: Match<T>) => { | |
const typeOfMaybeConstructor = maybe.val.type | |
const valueOfMaybe = maybe.val.val | |
return match_[typeOfMaybeConstructor](valueOfMaybe) | |
} | |
// ********************************************* | |
// USO: | |
function plus_one(x: Maybe<number>): Maybe<number> { | |
return match(x, { | |
None: () => None, | |
Just: (i) => Just(i+1) | |
}) | |
} | |
const five = Just(5) | |
const six = plus_one(five) | |
const none_ = plus_one(None) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
You may access the type inference test of Maybe here link