diff --git a/tsmonad/tests/either-tests.ts b/tsmonad/tests/either-tests.ts
new file mode 100644
index 000000000..1530562be
--- /dev/null
+++ b/tsmonad/tests/either-tests.ts
@@ -0,0 +1,45 @@
+///
+
+class User {
+
+ private age: number;
+
+ constructor(age?: number) {
+ this.age = age ? age : 0;
+ }
+
+ public getAge(): TsMonad.Either {
+ if (this.age > 0) {
+ return TsMonad.Either.right(this.age);
+ } else {
+ return TsMonad.Either.left('Information withheld');
+ }
+ }
+}
+
+module Station {
+
+ export class BusPass {
+
+ public isValidForRoute(route: string): boolean {
+ return true;
+ }
+ }
+
+ export function getBusPass(age: number): TsMonad.Either {
+ if (age > 18) {
+ return TsMonad.Either.right(new BusPass());
+ } else {
+ return TsMonad.Either.left('Too young for a bus pass');
+ }
+ }
+}
+
+var user = new User(42)
+
+var canRideForFree = user.getAge()
+ .bind(age => Station.getBusPass(age))
+ .caseOf({
+ right: busPass => busPass.isValidForRoute('Weston'),
+ left: errorMessage => { console.log(errorMessage); return false; }
+ });
diff --git a/tsmonad/tests/maybe-tests.ts b/tsmonad/tests/maybe-tests.ts
new file mode 100644
index 000000000..76f0a7256
--- /dev/null
+++ b/tsmonad/tests/maybe-tests.ts
@@ -0,0 +1,20 @@
+///
+
+var turns_out_to_be_100 = TsMonad.Maybe.just(10)
+ .caseOf({
+ just: n => n * n,
+ nothing: () => -1
+ });
+
+var turns_out_to_be_nothing = TsMonad.Maybe.nothing()
+ .caseOf({
+ just: n => n * n,
+ nothing: () => -1
+ });
+
+var turns_out_to_be_true = TsMonad.Maybe.just(123)
+ .lift(n => n * 2)
+ .caseOf({
+ just: n => n === 246,
+ nothing: () => false
+ });
\ No newline at end of file
diff --git a/tsmonad/tests/writer-tests.ts b/tsmonad/tests/writer-tests.ts
new file mode 100644
index 000000000..fd8200aeb
--- /dev/null
+++ b/tsmonad/tests/writer-tests.ts
@@ -0,0 +1,8 @@
+///
+
+var is_true = TsMonad.Writer.writer(['Started with 0'], 0)
+ .bind(x => TsMonad.Writer.writer(['+ 8'], x + 8))
+ .bind(x => TsMonad.Writer.writer(['- 6', '* 8'], 8 * (x - 6)))
+ .caseOf({
+ writer: (s, v) => v === 16 && s.join(', ') === 'Started with 0, + 8, - 6, * 8'
+ });
\ No newline at end of file
diff --git a/tsmonad/tsmonad-tests.ts b/tsmonad/tsmonad-tests.ts
new file mode 100644
index 000000000..8959950d9
--- /dev/null
+++ b/tsmonad/tsmonad-tests.ts
@@ -0,0 +1,3 @@
+///
+///
+///
diff --git a/tsmonad/tsmonad.d.ts b/tsmonad/tsmonad.d.ts
new file mode 100644
index 000000000..081c446c3
--- /dev/null
+++ b/tsmonad/tsmonad.d.ts
@@ -0,0 +1,640 @@
+// Type definitions for TsMonad
+// Project: https://github.com/cbowdon/TsMonad
+// Definitions by: Chris Bowdon
+// Definitions: https://github.com/borisyankov/DefinitelyTyped
+
+declare module TsMonad {
+ /**
+ * @name EitherType
+ * @description Enumerate the different types contained by an Either object.
+ */
+ enum EitherType {
+ Left = 0,
+ Right = 1,
+ }
+ /**
+ * @name EitherPatterns
+ * @description Define a contract to unwrap Either object using callbacks
+ * for Left and Right.
+ * @see Either#
+ */
+ interface EitherPatterns {
+ /**
+ * @name left
+ * @description Function to handle the Left.
+ * @type {(l: L) => T}
+ */
+ left: (l: L) => T;
+ /**
+ * @name right
+ * @description Function to handle the Right.
+ * @type {(r: R) => T}
+ */
+ right: (r: R) => T;
+ }
+ /**
+ * @name either
+ * @description Build an Either object.
+ * @function
+ * @param l The object as a Left (optional).
+ * @param r The object as a Right (optional).
+ * @returns {Either} Either object containing the input.
+ * @throws {TypeError} If there are both or none of left and right
+ * parameter.
+ * @see Either#
+ */
+ function either(l?: L, r?: R): Either;
+ /**
+ * @name Either
+ * @class Either has exactly two sub types, Left (L) and Right (R). If an
+ * Either object contains an instance of L, then the Either is a
+ * Left. Otherwise it contains an instance of R and is a Right. By
+ * convention, the Left constructor is used to hold an error value and
+ * the Right constructor is used to hold a correct value.
+ */
+ class Either implements Monad, Functor, Eq> {
+ private type;
+ private l;
+ private r;
+ /**
+ * @description Build an Either object. For internal use only.
+ * @constructor
+ * @methodOf Either#
+ * @param {EitherType} type Indicates if the Either content is a Left or a Right.
+ * @param {L} l The Left value (optional).
+ * @param {R} l The Right value (optional).
+ */
+ constructor(type: EitherType, l?: L, r?: R);
+ /**
+ * @name left
+ * @description Helper function to build an Either with a Left.
+ * @methodOf Either#
+ * @static
+ * @param {L} l The Left value.
+ * @returns {Either} Either object containing a Left.
+ */
+ static left(l: L): Either;
+ /**
+ * @name right
+ * @description Helper function to build an Either with a Right.
+ * @methodOf Either#
+ * @static
+ * @param {R} r The Right value.
+ * @returns {Either} Either object containing a Right.
+ */
+ static right(r: R): Either;
+ /**
+ * @name unit
+ * @description Wrap a value inside an Either Right object.
+ * @methodOf Either#
+ * @public
+ * @param {T} t
+ * @returns {Either} Either object containing a Right.
+ * @see Monad#unit
+ */
+ public unit(t: T): Either;
+ /**
+ * @name bind
+ * @description Apply the function passed as parameter on the object.
+ * @methodOf Either#
+ * @public
+ * @param {(r: R) => Either} f Function applied on the Right.
+ * @returns {Either} The result of the function f wrapped inside
+ * an Either object.
+ * @see Monad#bind
+ */
+ public bind(f: (r: R) => Either): Either;
+ /**
+ * @name of
+ * @description Alias for unit.
+ * @methodOf Either#
+ * @public
+ * @see Either#unit
+ * @see Monad#of
+ */
+ public of: (t: T) => Either;
+ /**
+ * @name chain
+ * @description Alias for bind.
+ * @methodOf Either#
+ * @public
+ * @see Either#bind
+ * @see Monad#chain
+ */
+ public chain: (f: (r: R) => Either) => Either;
+ /**
+ * @name fmap
+ * @description Apply the function passed as parameter on the object.
+ * @methodOf Either#
+ * @public
+ * @param {(r: R) => T} f Function applied on the Right.
+ * @returns {Either} The result of the function f wrapped inside
+ * an Either object.
+ * @see Functor#fmap
+ */
+ public fmap(f: (r: R) => T): Either;
+ /**
+ * @name lift
+ * @description Alias for fmap.
+ * @methodOf Either#
+ * @public
+ * @see Either#fmap
+ * @see Functor#lift
+ */
+ public lift: (f: (r: R) => T) => Either;
+ /**
+ * @name map
+ * @description Alias for fmap.
+ * @methodOf Either#
+ * @public
+ * @see Either#fmap
+ * @see Functor#map
+ */
+ public map: (f: (r: R) => T) => Either;
+ /**
+ * @name caseOf
+ * @description Execute a function depending on the Either content.
+ * It allows to unwrap the object for Left or Right types.
+ * @methodOf Either#
+ * @public
+ * @param {EitherPatterns} pattern Object containing the
+ * functions to applied on each Either types.
+ * @return {T} The returned value of the functions specified in the
+ * EitherPatterns interface.
+ * @see EitherPatterns#
+ */
+ public caseOf(pattern: EitherPatterns): T;
+ /**
+ * @name equals
+ * @description Compare the type and the content of two Either
+ * objects.
+ * @methodOf Either#
+ * @public
+ * @param {Either} other The Either to compare with.
+ * @return {boolean} True if the type and content value are equals,
+ * false otherwise.
+ * @see Eq#equals
+ */
+ public equals(other: Either): any;
+ }
+}
+declare module TsMonad {
+ /**
+ * @name eq
+ * @description Compare two objects :
+ * 1. if objects implement Eq, defer to their .equals
+ * 2. if are arrays, iterate and recur
+ * @function
+ * @param {any} a Any object.
+ * @param {any} b Any object.
+ * @returns {boolean} In case 1, the `.equals()` function returned value.
+ * In case 2, true if each elements are equals, false otherwise.
+ */
+ function eq(a: any, b: any): any;
+ /**
+ * @name Eq
+ * @description Define a contract to compare (in)equalities between
+ * objects.
+ */
+ interface Eq {
+ /**
+ * @name equals
+ * @description Determine if two objects are equals.
+ * @methodOf Eq
+ * @public
+ * @param {T} The object to compare with.
+ * @returns {boolean} True if the objects are equals, false otherwise.
+ */
+ equals(t: T): boolean;
+ }
+ interface Monad {
+ /**
+ * @name unit
+ * @description Wrap an object inside a monad.
+ * @methodOf Monad#
+ * @public
+ * @param {U} t The object to wrap.
+ * @returns {Monad} A Monad with the value wrapped inside.
+ */
+ unit(t: U): Monad;
+ /**
+ * @name bind
+ * @description Apply the function passed as parameter on the object.
+ * @methodOf Monad#
+ * @public
+ * @param {(t: T) => Monad} f Function applied on the Monad content.
+ * @returns {Monad} The result of the function f wrapped inside
+ * a Monad object.
+ */
+ bind(f: (t: T) => Monad): Monad;
+ /**
+ * @name of
+ * @description Alias for unit. Fantasy Land Monad conformance.
+ * @methodOf Monad#
+ * @public
+ * @see Monad#unit
+ */
+ of(t: U): Monad;
+ /**
+ * @name chain
+ * @description Alias for bind. Fantasy Land Monad conformance.
+ * @methodOf Monad#
+ * @public
+ * @see Monad#bind
+ */
+ chain(f: (t: T) => Monad): Monad;
+ }
+ /**
+ * @name Functor
+ * @description Define a contract to add basic functor functions to an
+ * object.
+ */
+ interface Functor {
+ /**
+ * @name fmap
+ * @description Apply the function passed as parameter on the object.
+ * @methodOf Functor#
+ * @public
+ * @param {(t: T) => U} f Function applied on the functor content.
+ * @returns {Functor} The result of the function f wrapped inside
+ * an Functor object.
+ * @see Functor#fmap
+ */
+ fmap(f: (t: T) => U): Functor;
+ /**
+ * @name lift
+ * @description Alias for fmap.
+ * @methodOf Functor#
+ * @public
+ * @see Functor#fmap
+ */
+ lift(f: (t: T) => U): Functor;
+ /**
+ * @name map
+ * @description Alias for fmap. Fantasy Land Monad conformance.
+ * @methodOf Functor#
+ * @public
+ * @see Functor#fmap
+ */
+ map(f: (t: T) => U): Functor;
+ }
+}
+declare module TsMonad {
+ /**
+ * @name MaybeType
+ * @description Enumerate the different types contained by an Maybe object.
+ * @see Maybe#
+ */
+ enum MaybeType {
+ Nothing = 0,
+ Just = 1,
+ }
+ /**
+ * @name MaybePatterns
+ * @description Define a contract to unwrap Maybe object using callbacks
+ * for Just and Nothing.
+ * @see Maybe#
+ */
+ interface MaybePatterns {
+ /**
+ * @name just
+ * @description Function to handle the Just.
+ * @type {(t: T) => U}
+ */
+ just: (t: T) => U;
+ /**
+ * @name nothing
+ * @description Function to handle the Nothing.
+ * @type {() => U}
+ */
+ nothing: () => U;
+ }
+ /**
+ * @name maybe
+ * @description Build a Maybe object.
+ * @function
+ * @param {T} t The object to wrap.
+ * @returns {Maybe} A Maybe object containing the input. If t is null
+ * or undefined, the Maybe object is filled with Nothing.
+ * @see Maybe#
+ */
+ function maybe(t: T): Maybe;
+ /**
+ * @name Maybe
+ * @class Encapsulates an optional value. A value of type Maybe a either
+ * contains a value of type a (represented as Just a), or it is empty
+ * (represented as Nothing).
+ */
+ class Maybe implements Monad, Functor, Eq> {
+ private type;
+ private value;
+ /**
+ * @description Build a Maybe object. For internal use only.
+ * @constructor
+ * @methodOf Maybe#
+ * @param {MaybeType} type Indicates if the Maybe content is a Just or a Nothing.
+ * @param {T} value The value to wrap (optional).
+ */
+ constructor(type: MaybeType, value?: T);
+ /**
+ * @name maybe
+ * @description Helper function to build a Maybe object.
+ * @methodOf Maybe#
+ * @static
+ * @param {T} t The value to wrap.
+ * @returns {Maybe} A Maybe object containing the value passed in input. If t is null
+ * or undefined, the Maybe object is filled with Nothing.
+ */
+ static maybe(t: T): Maybe;
+ /**
+ * @name just
+ * @description Helper function to build a Maybe object filled with a
+ * Just type.
+ * @methodOf Maybe#
+ * @static
+ * @param {T} t The value to wrap.
+ * @returns {Maybe} A Maybe object containing the value passed in input.
+ * @throws {TypeError} If t is null or undefined.
+ */
+ static just(t: T): Maybe;
+ /**
+ * @name nothing
+ * @description Helper function to build a Maybe object filled with a
+ * Nothing type.
+ * @methodOf Maybe#
+ * @static
+ * @returns {Maybe} A Maybe with a Nothing type.
+ */
+ static nothing(): Maybe;
+ /**
+ * @name unit
+ * @description Wrap an object inside a Maybe.
+ * @public
+ * @methodOf Maybe#
+ * @param {U} u The object to wrap.
+ * @returns {Monad} A Monad with the value wrapped inside.
+ * @see Monad#unit
+ */
+ public unit(u: U): Maybe;
+ /**
+ * @name bind
+ * @description Apply the function passed as parameter on the object.
+ * @methodOf Maybe#
+ * @public
+ * @param {(t: T) => Maybe} f Function applied on the Maybe content.
+ * @returns {Maybe} The result of the function f wrapped inside
+ * a Maybe object.
+ * @see Monad#bind
+ */
+ public bind(f: (t: T) => Maybe): Maybe;
+ /**
+ * @name of
+ * @description Alias for unit.
+ * @methodOf Maybe#
+ * @public
+ * @see Maybe#unit
+ * @see Monad#of
+ */
+ public of: (u: U) => Maybe;
+ /**
+ * @name chain
+ * @description Alias for bind.
+ * @methodOf Maybe#
+ * @public
+ * @see Maybe#unit
+ * @see Monad#of
+ */
+ public chain: (f: (t: T) => Maybe) => Maybe;
+ /**
+ * @name fmap
+ * @description Apply the function passed as parameter on the object.
+ * @methodOf Maybe#
+ * @public
+ * @param {(t: T) => U} f Function applied on the Maybe content.
+ * @returns {Maybe} The result of the function f wrapped inside
+ * an Maybe object.
+ * @see Functor#fmap
+ */
+ public fmap(f: (t: T) => U): Maybe;
+ /**
+ * @name lift
+ * @description Alias for fmap.
+ * @methodOf Maybe#
+ * @public
+ * @see Maybe#fmap
+ * @see Monad#of
+ */
+ public lift: (f: (t: T) => U) => Maybe;
+ /**
+ * @name map
+ * @description Alias for fmap.
+ * @methodOf Maybe#
+ * @public
+ * @see Maybe#fmap
+ * @see Monad#of
+ */
+ public map: (f: (t: T) => U) => Maybe;
+ /**
+ * @name caseOf
+ * @description Execute a function depending on the Maybe content. It
+ * allows to unwrap the object for Just or Nothing types.
+ * @methodOf Maybe#
+ * @public
+ * @param {MaybePatterns} pattern Object containing the
+ * functions to applied on each Maybe types.
+ * @return {U} The returned value of the functions specified in the
+ * MaybePatterns interface.
+ * @see MaybePatterns#
+ */
+ public caseOf(patterns: MaybePatterns): U;
+ /**
+ * @name equals
+ * @description Compare the type and the content of two Maybe
+ * objects.
+ * @methodOf Maybe#
+ * @public
+ * @param {Maybe} other The Maybe to compare with.
+ * @return {boolean} True if the type and content value are equals,
+ * false otherwise.
+ * @see Eq#equals
+ */
+ public equals(other: Maybe): any;
+ }
+}
+declare module TsMonad {
+ /**
+ * @name WriterPatterns
+ * @description Define a contract to unwrap Writer object using a
+ * callback.
+ * @see Writer#
+ */
+ interface WriterPatterns {
+ /**
+ * @name writer
+ * @description Function to handle the Writer content.
+ * @type {(story: S[], value: T) => U}
+ */
+ writer: (story: S[], value: T) => U;
+ }
+ /**
+ * @name writer
+ * @description Build a Writer object.
+ * @function
+ * @param {S[]} story The collection to store logs.
+ * @param {T} value The object to wrap.
+ * @returns {Writer} A Writer object containing the log collection
+ * and the wrapped value.
+ * @see Writer#
+ */
+ function writer(story: S[], value: T): Writer;
+ /**
+ * @name Writer
+ * @class Allow to do computations while making sure that all the log
+ * values are combined into one log value that then gets attached to
+ * the result.
+ */
+ class Writer implements Monad, Eq> {
+ private story;
+ private value;
+ /**
+ * @description Build a Writer object. For internal use only.
+ * @constructor
+ * @methodOf Writer#
+ * @param {S[]} story The collection of logs.
+ * @param {T} value The object to wrap.
+ */
+ constructor(story: S[], value: T);
+ /**
+ * @name writer
+ * @description Helper function to build a Writer object.
+ * @methodOf Writer#
+ * @static
+ * @param {S[]} story The collection of logs.
+ * @param {T} value The object to wrap.
+ * @returns {Writer} A Writer object containing the collection of logs
+ * and the wrapped value.
+ */
+ static writer(story: S[], value: T): Writer;
+ /**
+ * @name writer
+ * @description Helper function to build a Writer object with the log
+ * passed in input only.
+ * @methodOf Writer#
+ * @static
+ * @param {S} s A log to store.
+ * @returns {Writer} A Writer object containing the collection of logs
+ * and a zeroed value.
+ */
+ static tell(s: S): Writer;
+ /**
+ * @name unit
+ * @description Wrap an object inside a Writer.
+ * @public
+ * @methodOf Writer#
+ * @param {U} u The object to wrap.
+ * @returns {Monad} A Writer with the value wrapped inside and an
+ * empty collection of logs.
+ * @see Monad#unit
+ */
+ public unit(u: U): Writer;
+ /**
+ * @name bind
+ * @description Apply the function passed as parameter on the object.
+ * @methodOf Writer#
+ * @public
+ * @param {(t: T) => Writer} f Function applied on the Writer content.
+ * @returns {Writer} The result of the function f append to the
+ * Writer object.
+ * @see Monad#bind
+ */
+ public bind(f: (t: T) => Writer): Writer;
+ /**
+ * @name of
+ * @description Alias for unit.
+ * @methodOf Writer#
+ * @public
+ * @see Writer#unit
+ * @see Monad#of
+ */
+ public of: (u: U) => Writer;
+ /**
+ * @name chain
+ * @description Alias for bind
+ * @methodOf Writer#
+ * @public
+ * @see Writer#unit
+ * @see Monad#of
+ */
+ public chain: (f: (t: T) => Writer) => Writer;
+ /**
+ * @name fmap
+ * @description Apply the function passed as parameter on the object.
+ * @methodOf Writer#
+ * @public
+ * @param {(t: T) => U} f Function applied on the wrapped value.
+ * @returns {Writer} The result of the function f wrapped inside
+ * an Writer object. It has an empty collection of logs.
+ * @see Functor#fmap
+ */
+ public fmap(f: (t: T) => U): Writer;
+ /**
+ * @name lift
+ * @description Alias for fmap
+ * @methodOf Writer#
+ * @public
+ * @see Writer#fmap
+ * @see Monad#of
+ */
+ public lift: (f: (t: T) => U) => Writer;
+ /**
+ * @name map
+ * @description Alias for fmap
+ * @methodOf Writer#
+ * @public
+ * @see Writer#fmap
+ * @see Monad#of
+ */
+ public map: (f: (t: T) => U) => Writer;
+ /**
+ * @name caseOf
+ * @description Execute a function on the Writer content. It allows to
+ * unwrap the object.
+ * @methodOf Writer#
+ * @public
+ * @param {WriterPatterns} pattern Object containing the
+ * functions to applied on the Writer content.
+ * @return {U} The returned value of the function specified in the
+ * WriterPatterns interface.
+ * @see WriterPatterns#
+ */
+ public caseOf(patterns: WriterPatterns): U;
+ /**
+ * @name equals
+ * @description Compare the type and the content of two Writer
+ * objects.
+ * @methodOf Writer#
+ * @public
+ * @param {Writer} other The Writer to compare with.
+ * @return {boolean} True if the collection of logs and content value
+ * are equals, false otherwise.
+ * @see Eq#equals
+ */
+ public equals(other: Writer): boolean;
+ }
+}
+declare var module: {
+ exports: any;
+ require(id: string): any;
+ id: string;
+ filename: string;
+ loaded: boolean;
+ parent: any;
+ children: any[];
+};
+/**
+* @name tsmonad
+* @namespace Hold functionalities related to TsMonad library.
+*/
+declare module 'tsmonad' {
+ export = TsMonad;
+}