柯里化、函数式编程

// 柯里化
function getSum(x) {
    return function (y) {
        return x + y
    }
}
console.log(getSum(5)(6));
console.log(getSum(9));
function getSum2(f, g) {
    return function (x) {
        return f(g(x))
    }
}
var getSum3 = (f, g) => x => f(g(x))
var s = getSum2(x => x + 1, y => y * 2)(5)
var s1 = getSum3(x => x + 1, y => y * 2)(5)
console.log(s);
console.log(s1);


// 它的map方法接受函数f作为参数,然后返回一个新的函子,里面包含的值是被f处理过的(f(this.val))。of方法:函数式编程一般约定,函子有一个of方法,用来生成新的容器。
class Functor {
    constructor(val) {
        this.val = val
    }
    map(f) {
        return this.val ? Functor.of(f(this.val)) : Functor.of(null)
    }
}
Functor.of = function (val) {
    return new Functor(val)
}

// console.log(new Functor(2).map(x=>x+2).val);
var fff = Functor.of(null).map(function (s) {
    return s.toUpperCase()
})
// console.log(fff);

// Either 函子内部有两个值:左值(Left)和右值(Right)。右值是正常情况下使用的值,左值是右值不存在时使用的默认值。
class Either extends Functor{
    constructor(left,right){
        super()
        this.left = left;
        this.right = right;
    }
    map(f){
        return this.right ? Either.of(this.left,f(this.right)) : 
        Either.of(f(this.left),this.right)
    }
}
Either.of = function(left,right){
    return new Either(left,right)
}
var addOne = function(x){
    return x + 1
}
Either.of(5,6).map(addOne)
Either.of(1,null).map(addOne)

// 上面代码中,如果右值有值,就使用右值,否则使用左值。通过这种方式,Either 函子表达了条件运算。
// Either 函子的常见用途是提供默认值。下面是一个例子。
// Either.of({address:'xxx'},currentUser.address).map(updateField)
// 上面代码中,如果用户没有提供地址,Either 函子就会使用左值的默认地址。
// Either函子的另一个用途是代替try...catch,使用左值表示错误
function parseJSON(json){
    try{
        return Either.of(null,JSON.parse(json))
    } catch(e){
    // } catch(e:Error){
        return Either.of(e,null)
    }
}

// 上面代码中,左值为空,就表示没有出错,否则左值会包含一个错误对象e。一般来说,所有可能出错的运算,都可以返回一个 Either 函子。

class Ap extends Functor {
    ap(F) {
        return Ap.of(this.val(F.val))
    }
}
Ap.of = function (val) {
    return new Ap(val)
}
function addTwo(x) {
    return x + 2
}
console.log(Ap.of(addTwo).ap(Functor.of(2)));

// 函子接受各种函数,处理容器内部的值。这里就有一个问题,容器内部的值可能是一个空值(比如null),而外部函数未必有处理空值的机制,如果传入空值,很可能就会出错。
class Maybe extends Functor {
    map(f) {
        return this.val ? Maybe.of(f(this.val)) : Maybe.of(null)
    }
}
// ap函子:函子里面包含的值,完全可能是函数。我们可以想象这样一种情况,一个函子的值是数值,另一个函子的值是函数。
// 链式应用
function add(x) {
    return function (y) {
        return function (z) {
            return x + y + z
        }
    }
}
var bbb = Ap.of(add).ap(Maybe.of(2)).ap(Maybe.of(3)).ap(Maybe.of(4))
console.log(bbb);

// Monad函子
// 函子是一个容器,可以包含任何值。函子之中再包含一个函子,也是完全合法的。但是,这样就会出现多层嵌套的函子。
// Monad 函子的作用是,总是返回一个单层的函子。它有一个flatMap方法,与map方法作用相同,唯一的区别是如果生成了一个嵌套函子,它会取出后者内部的值,保证返回的永远是一个单层的容器,不会出现嵌套的情况。
Maybe.of(
    Maybe.of(
        Maybe.of({
            name:'plus',
            number:88888888
        })
    )
)
class Monad extends Functor{
    join(){
        return this.val
    }
    flatMap(f){
        return this.map(f).join()
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值