Skip to content

Instantly share code, notes, and snippets.

@ruxo
Last active May 27, 2017 07:30
Show Gist options
  • Select an option

  • Save ruxo/e3f81db741b62b274f134e9f2fde4ee5 to your computer and use it in GitHub Desktop.

Select an option

Save ruxo/e3f81db741b62b274f134e9f2fde4ee5 to your computer and use it in GitHub Desktop.
FP prelude for TypeScript
declare module "data.task" {
type Func<A,B> = (_:A) => B
class Task<TFail,TOk> {
constructor(f: (reject: Func<TFail,any>, resolve: Func<TOk,any>) => void)
static of<TFail,TOk>(v: TOk): Task<TFail,TOk>
static rejected<TFail,TOk>(v: TFail): Task<TFail,TOk>
map<C>(f: Func<TOk,C>) :Task<TFail,C>
chain<A>(f: Func<TOk,Task<TFail,A>>) :Task<TFail,A>
ap(v:any): any
cata<F,Ok>(f: { Rejected: Func<TFail,F>, Resolved: Func<TOk,Ok> }): Task<F,Ok>
fork<T>(reject: Func<TFail,any>, resolve: Func<TOk,any>): void
}
export = Task
}
export type Func<A,B> = (_:A) => B
export type Action<T> = () => T
export function id<T>(x: T) { return x }
export function seq2<A,B,C>(f1: Func<A,B>, f2: Func<B,C>){
return (x: A) => f2(f1(x))
}
export interface Result<S,F> {
get<T>(f: { success: Func<S,T>, failed: Func<F,T>}) :T
map<T>(f: Func<S,T>) :Result<T,F>
chain<T>(f: Func<S,Result<T,F>>) :Result<T,F>
perform(f: { success: Func<S,void>, failed: Func<F,void> }): void
}
class Success<S,F> implements Result<S,F> {
data: S
constructor(v: S) {
this.data = v
}
get<T>(f: { success: Func<S,T>, failed: Func<F,T>}) :T { return f.success(this.data) }
map<T>(f: Func<S,T>) :Result<T,F> { return new Success(f(this.data)) }
chain<T>(f: Func<S,Result<T,F>>) :Result<T,F> { return f(this.data) }
perform(f: { success: Func<S,void>, failed: Func<F,void> }): void { f.success(this.data) }
}
class Failed<S,F> implements Result<S,F> {
data: F
constructor(v: F) {
this.data = v
}
get<T>(f: { success: Func<S,T>, failed: Func<F,T>}) :T { return f.failed(this.data) }
map<T>(_: Func<S,T>) :Result<T,F> { return new Failed(this.data) }
chain<T>(_: Func<S,Result<T,F>>) :Result<T,F> { return new Failed(this.data) }
perform(f: { success: Func<S,void>, failed: Func<F,void> }): void { f.failed(this.data) }
}
export module Result {
export function success<S,F>(value: S): Result<S,F> {
return new Success<S,F>(value)
}
export function failed<S,F>(value: F): Result<S,F> {
return new Failed<S,F>(value)
}
}
export interface Option<T> {
isSome(): boolean
isNone(): boolean
map<V>(f: Func<T,V>): Option<V>
chain<V>(f: Func<T,Option<V>>): Option<V>
chainDefined<V>(f: Func<T,V|undefined>): Option<V>
get<V>(f: { some: Func<T,V>, none: Action<V> }): V
perform(f: { some: Func<T,void>, none: Action<void> }): void
}
class Some<T> implements Option<T> {
value: T
constructor(value: T){
this.value = value
}
isSome(): boolean { return true }
isNone(): boolean { return false }
map<V>(f: Func<T,V>) { return new Some<V>(f(this.value)) }
chain<V>(f: Func<T,Option<V>>): Option<V> { return f(this.value) }
get<V>(f: { some: Func<T,V>, none: Action<V> }): V { return f.some(this.value) }
perform(f: { some: Func<T,void>, none: Action<void> }): void { f.some(this.value) }
chainDefined<V>(f: Func<T,V|undefined>): Option<V> {
const ret = f(this.value)
return ret === undefined? Option.none<V>() : Option.some<V>(ret)
}
}
class None<T> implements Option<T> {
isSome(): boolean { return false }
isNone(): boolean { return true }
map<V>(_: Func<T,V>) { return this }
chain<V>(_: Func<T,Option<V>>): Option<V> { return <Option<V>> <any> this }
get<V>(f: { some: Func<T,V>, none: Action<V> }): V { return f.none() }
perform(f: { some: Func<T,void>, none: Action<void> }): void { f.none() }
chainDefined<V>(_: Func<T,V|undefined>): Option<V> { return <Option<V>> <any> this }
}
export module Option {
export function ofDefined<T>(x: T): Option<T> {
return x === undefined? new None<T>() : new Some<T>(x)
}
export function ofNullable<T>(x: T): Option<T> {
return x === null || x === undefined? new None<T>() : new Some<T>(x)
}
export function some<T>(x: T): Option<T> {
return new Some<T>(x)
}
export function none<T>(): Option<T> {
return new None<T>()
}
}
export function lazy<T>(f: Action<T>) :Action<T> {
let v: (T|undefined) = undefined
return () => v || (v = f())
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment