函數式functor的理解

// 參考
// http://jiyinyiyong.github.io/monads-in-pictures/
// https://llh911001.gitbooks.io/mostly-adequate-guide-chinese/content/ch8.html
// https://zhuanlan.zhihu.com/p/21926955
// https://zhuanlan.zhihu.com/p/22094473

// functor就是一個容器
var Container = function(x) {
  this.__value = x;
}

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

// map函數的參數是一個函數。這個函數用來運算容器裏面的值。
Container.prototype.map = function(f){
  return Container.of(f(this.__value))
};
Container.of(2).map(function(two){ return two + 2 }).map(function(num){return num * 2 });




// 高級一點的functor,能夠處理null的functor。
var 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(f) {
  return this.isNothing() ? Maybe.of(null) : Maybe.of(f(this.__value));
};

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

Maybe.of({name: "Boris"}).map(function(obj){return obj['age'] }).map(function(num){return num + 10});
Maybe.of(3).map(function(num){return num + 2; }).map(function(num){return num + 5});

console.log('點的連續運算', Maybe.of(3).map(function(num){return num + 2; }).map(function(num){return num + 5}) );
console.log('函數組合',Maybe.of(function(num){return num + 2}).map(function(num){return num + 3}));

// 儘管Maybe會返回null,可是咱們不知道它從哪返回,也沒有更多異常信息。
// 錯誤捕獲
var Left = function(x) {
  this.__value = x;
}
var Right = function(x) {
  this.__value = x;
}

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

Left.prototype.map = function(f) {
  return this;
};
Right.prototype.map = function(f) {
  return Right.of(f(this.__value));
};

var either = function(f, g, e) {
  switch(e.constructor) {
    case Left: return f(e.__value);
    case Right: return g(e.__value);
  }
};

var a = Maybe.of({name: "Boris"}).map(function(obj){
    if(obj['name']){return Right.of('has age')}
    else{
        return Left.of('no age');
    } 
})
// .map(function(num){return num + 10}).map(function(num){return num + 1});
console.log('a',a);

// 另類functor,惰性求值,用來接觸外面的世界。把反作用操做( IO操做、異步請求、DOM操做)包裹起來。
var IO = function(f) {
  this.__value = f;
};

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

IO.prototype.map = function(f) {
  return new IO(f(this.__value));
};

// 能夠鏈式調用。
// 能夠進行函數組合。
// 處理反作用。常見的反作用包括異常和異步。
// 咱們很快想到數組也是一個容器functor,該容器的map函數也是用來運算容器裏面的值。
// promise也是一個容器functor。


// Applicative是一個起子,用來打開容器。
// 把容器裏的函數應用到容器裏的值。
相關文章
相關標籤/搜索