Last active
May 27, 2017 07:30
-
-
Save ruxo/e3f81db741b62b274f134e9f2fde4ee5 to your computer and use it in GitHub Desktop.
FP prelude for TypeScript
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
| 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 | |
| } |
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
| 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