class Functor {
constructor(val) {
this.val = val
}
static of(val) {
return new Functor(val)
}
map(f) {
return new Functor(f(this.val))
}
}
class Maybe extends Functor {
static of(val) {
return new Maybe(val)
}
map(f) {
return this.val ? Maybe.of(f(this.val)) : Maybe.of(null)
}
}
class Either extends Functor {
constructor(left, right) {
super()
this.left = left
this.right = right
}
static of(left, right) {
return new Either(left, right)
}
map(f) {
return this.right ?
Either.of(this.left, f(this.right)) :
Either.of(f(this.left), this.right)
}
}
class Ap extends Functor {
constructor(val) {
super()
this.val = val
}
static of(val) {
return new Ap(val)
}
ap(F) {
return Ap.of(this.val(F.val))
}
}
class Monad extends Functor {
join() {
return this.val
}
map(f) {
return new Monad(f(this.val()))
}
flatMap(f) {
return this.map(f).join()
}
}
const readFile = function() {
return new Monad(function() {
return '我是你爸爸。'
})
}
const tail = function(x) {
return new Monad(function() {
return x.substring(0, x.length - 1)
})
}
const print = function(x) {
return new Monad(function() {
console.log(x)
return x
})
}
const content = readFile()
.flatMap(tail)
.flatMap(print)
.val()
console.log(content)