// Generic Monad structure
class Monad {
constructor(value) {
this.value = value;
}
// Bind: chains computations that return a Monad
bind(fn) {
return fn(this.value);
}
// Unit: wraps a value in the Monad
static of(value) {
return new Monad(value);
}
// For debugging
get() {
return this.value;
}
}
// Example: Maybe Monad
class Maybe extends Monad {
bind(fn) {
if (this.value == null) {
return new Maybe(null);
}
return fn(this.value);
}
static of(value) {
return new Maybe(value);
}
getOrElse(defaultValue) {
return this.value == null ? defaultValue : this.value;
}
}
// Demo: chaining computations with Monad
const double = x => Monad.of(x * 2);
const increment = x => Monad.of(x + 1);
const result = Monad.of(5)
.bind(double) // 10
.bind(increment); // 11
console.log(result.get()); // Output: 11
// Demo: chaining with Maybe Monad
const safeDivide = x => x === 0 ? Maybe.of(null) : Maybe.of(10 / x);
const maybeResult = Maybe.of(2)
.bind(safeDivide) // 10 / 2 = 5
.bind(x => Maybe.of(x + 3)); // 8
console.log(maybeResult.getOrElse("fail")); // Output: 8
const maybeFail = Maybe.of(0)
.bind(safeDivide) // null
.bind(x => Maybe.of(x + 3));
console.log(maybeFail.getOrElse("fail")); // Output: "fail"