Skip to content

Instantly share code, notes, and snippets.

@fvilante
Last active September 17, 2019 20:17
Show Gist options
  • Save fvilante/6ce13329bf307d307a040a63b70fe560 to your computer and use it in GitHub Desktop.
Save fvilante/6ce13329bf307d307a040a63b70fe560 to your computer and use it in GitHub Desktop.
Pattern Match
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)
}
@fvilante
Copy link
Author

You may access the type inference test of Maybe here link

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment