/**
*
*  Maybe Monad
*  @Source: https://codewithstyle.info/advanced-functional-programming-in-typescript-maybe-monad/
*  @Modified by: @lucascalion - 28/08/2019
*
**/
export class Maybe<T> {
  private constructor(private value: T | null) {}

  static some<T>(value: T) {
      if (!value) {
          throw Error("Provided value must not be empty");
      }
      return new Maybe(value);
  }

  static none<T>() {
      return new Maybe<T>(null);
  }

  static fromValue<T>(value: T) {
      return value ? Maybe.some(value) : Maybe.none<T>();
  }

  getOrElse(defaultValue: T) {
      return this.value === null ? defaultValue : this.value;
  }

  map<R>(f: (wrapped: T) => R): Maybe<R> {
    if (this.value === null) {
        return Maybe.none<R>();
    } else {
        return Maybe.fromValue(f(this.value));
    }
}
}