Skip to content

Instantly share code, notes, and snippets.

@awkward-ninja
Last active December 24, 2022 09:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save awkward-ninja/f7834c7edc0243c754da1742af75465a to your computer and use it in GitHub Desktop.
Save awkward-ninja/f7834c7edc0243c754da1742af75465a to your computer and use it in GitHub Desktop.
Javascript Monads
class Option {
constructor(some, value) {
this.some = some
this.value = value
}
map(next) {
return this.some ? next(this.value) : this
}
toString() {
return this.some ? `Some(${this.value})` : 'None'
}
}
function from(value) {
return new Option(true, value)
}
const NONE = new Option(false)
console.log(
from(15)
.map(i => i % 2 === 0 ? from(i / 2) : NONE)
.map(i => i % 3 === 0 ? from(i / 3) : NONE)
.toString(),
from(16)
.map(i => i % 2 === 0 ? from(i / 2) : NONE)
.map(i => i % 3 === 0 ? from(i / 3) : NONE)
.toString(),
from(17)
.map(i => i % 2 === 0 ? from(i / 2) : NONE)
.map(i => i % 3 === 0 ? from(i / 3) : NONE)
.toString(),
from(18)
.map(i => i % 2 === 0 ? from(i / 2) : NONE)
.map(i => i % 3 === 0 ? from(i / 3) : NONE)
.toString()
)
class Reader {
constructor(get) {
this.get = get
}
map(next) {
return from(config => next(this.get(config)).get(config))
}
}
function from(get) {
return new Reader(get)
}
function cased(get) {
return from(get).map(msg => from(({ upper }) => upper ? msg.toUpperCase() : msg))
}
console.log(
cased(({ name }) => `Hello ${name}.`).map(greeting =>
cased(({ pet }) => `Don't forget to feed ${pet}.`).map(reminder =>
cased(({ name }) => `Have a nice day, ${name}!`).map(farewell =>
from(() => `${greeting} ${reminder} ${farewell}`)
)
)
)
.get({
upper: false,
name: "Ken",
pet: "the dog"
})
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment