js-函数式编程-monad-chain-mcompose-自动解嵌套

chain和mcompose的例子:

import fs from 'fs'
import path from 'path'
import * as R from 'ramda'
const trace = R.curry((label, v) => {
  console.log(label, v)
  return v
})
const Maybe = function(x) {
  this.__value = x
}

Maybe.of = function(x) {
  return new Maybe(x);
}

Maybe.prototype.isNothing = function() {
  return (this.__value === null) || (this.__value === undefined);
}

Maybe.prototype.map = function(fun) {
  return this.isNothing() ? Maybe.of(null) : Maybe.of(fun(this.__value));
}

Maybe.prototype.join = function() {
  return this.isNothing() ? this.of(null): this.__value
}
const join = function(mma) {
  return mma.join()
}

const map = R.curry(function(f, any_functor_at_all) {
  return any_functor_at_all.map(f);
});

let threeFn = v => Maybe.of(2).map(R.add(v))
let r = Maybe.of(3).map(threeFn).join().join() // 需要手动连续解两层
console.log(r)

// 使用chain
// 写法1
const chain = R.curry((f, m) => {
  return R.compose(join, map(f))(m)
})
let res = chain(function(three) {
  return Maybe.of(2).map(R.add(three));
}, Maybe.of(3))
console.log(res)

// 写法2
Maybe.prototype.chain = function(f) {
  return R.compose(join, map(f))(this)
}
let sum = Maybe.of(3).chain( v => Maybe.of(2).chain(R.add(v)) )
console.log(sum)

// 进一步优化
// mcompose
const mcompose = function(f, g) {
  return R.compose(chain(f), chain(g))
}

// 当有两个及以上chain时
const addFn = R.curry((n, v) => Maybe.of(n).map(R.add(v))) 
let sum2 = R.compose(
  chain(addFn(5)),
  chain(addFn(2))
)
console.log(sum2(Maybe.of(3)))

// 使用mcompose
let res2 = mcompose(
  addFn(5),
  addFn(2)
)
console.log(res2(Maybe.of(3)))

  • 每次使用map都会导致新增一个容器
  • join用于手动解除容器包装
  • 使用chain自动解包装
  • mcompose 封装了compose和chain,语义清晰,使用简洁
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值