国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

[譯]淺入淺出Monads

philadelphia / 1316人閱讀

摘要:接受另一個函數作為參數,然后用接受的這個新函數處理,將結果再次傳給,最后將實例化的新對象返回。空值檢查就是個不錯的例子這個實現里,只在為合法值非空時,傳入。但不論怎么變化,她們也都和一樣遵守上面提到的規則。

大多數關于monad的教程都和老太太的裹腳布一樣,又臭、又長,說不清、道不明。當然我也不偉大,沒法保證我寫的一定更明了,更生動,甚至更屌?不過我至少可以確定,我這篇更簡潔。浪費不了你多少時間的!

廢話不多說,先看下面這個對象Foo。她就是個monad。你必定會吃驚道:我擦,這是什么意思?不要急,故事要從頭說,我們還是先來分析下Foo到底是怎么干活的:

function Foo(value) {
    this.get = ()=> value;
    this.map = fn => {
        let result = fn(value);
        return new Foo(result);
    };
}

Foo接受了一個value,而且一直都沒改變她的值。Foo里提供了一個get方法使得外部調用者可以獲取value,還有一個牛逼的方法叫mapmap接受另一個函數(handler)作為參數,然后用接受的這個新函數handler處理value,將結果再次傳給Foo,最后將實例化的新Foo對象返回。

因為map返回一個Foo的實例,于是map的方法是可以被鏈式調用的:

let one = new Foo(1);
let two = one.map(x => x + 7).map(x => x / 2).map(x => x - 2);
two.get() === 2;

鏈式調用high不 high?她允許我們可以按照期望,對x執行順序操作,這種更“自然”的風格絕對比下面這種瘋狂嵌套的風格要好:

//嵌套組合的方式長這個樣子,
//我們必須從右向左讀,才能得出結論
//而且你說實話,這風格,你喜歡么?
let two = minusTwo(divideByTwo(addSeven(1)));

而且每一個步驟里處理value到下一個Foo實例的邏輯我們都可以抽離出去。

再來看看另一個monad,我們姑且稱之為Bar吧:

function Bar(value) {
  this.get = ()=> value;
  this.map = fn => {
      let result = fn(value);
      console.log(result);
      return new Bar(result);
  };
}

如果這時候我有一系列操作想順序作用在value上,而且還要在每次變化時打印出來新的value,就可以利用Bar把下面這種原始的,二逼的代碼:

let stepOne = something(1);
console.log(stepOne);
let stepTwo = somethingElse(stepOne);
console.log(stepTwo);
let stepThree = somethingDifferent(stepTwo);
console.log(stepThree);

重構成下面這種優雅的,高端的樣子了:

new Bar(1)
  .map(something)           // console >> logs new value
  .map(somethingElse)       // console >> logs new value
  .map(somethingDifferent); // console >> logs new value

現在你應該懂什么是monads。我完成諾言了哦!Monads可以粗略的歸納出下面這些規則:

monad總會包含一個值

monad有一個map方法,而且該方法會接受一個函數(handler)作為參數

map通過上一步提到的handler處理value(還可能有些其他邏輯),并獲取其結果

map最后返回一個new [Monad],以完成鏈式調用

目前能想到的就這些了。如果上述的例子你都理解了,那你就懂什么是Monads了。如果你還再等什么黑魔法或者驚奇算法,那抱歉了,還真沒有!

理論上,我們任意修改map的實現,任何可以在各步驟handler之間的邏輯都行 - 例如:決定傳什么內容到下一步,或者對上一步handler處理的結果做點兒什么。

空值檢查就是個不錯的例子:

function Maybe(value) {
  this.get = ()=> value;
  this.map = fn => {
      if (value === null) {
          return new Maybe(null);
      } else {
          return new Maybe(fn(value));
      }
  };
}

這個實現里,map只在value為合法值(非空)時,傳入handler。否則就只返回一個自身的copy。利用上面的非空檢查的Monad函數Maybe,我們可以把下面這個冗長矬的代碼:

let connection = getConnection();
let user = connection ? connection.getUser() : null;
let address = user ? user.getAddress() : null;
let zipCode = address ? address.getZip() : null;

重構成這個樣子:

let zipCode =
    new Maybe(getConnection())
    .map(c => c.getUser())
    .map(u => u.getAddress())
    .map(a => a.getZip());

//最后得到的要么是真正的zipCode(每一步都正確處理)
//要么就是個null
zipCode.get();

希望今天的說教已經說明了monads和她的map方法為什么這么牛逼了!關于這點,我倒是不懷疑你也能自己想出來^^

還有其他很多種monads,都有不同的用法和用途。但不論怎么變化,她們也都和FooBar一樣遵守上面提到的規則。

掌握了這些技巧,你基本就可以裝做一個會寫函數式的“牛人”了!

原文地址:Monads Explained Quickly

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/79149.html

相關文章

  • SegmentFault 技術周刊 Vol.16 - 淺入淺出 JavaScript 函數式編程

    摘要:函數式編程,一看這個詞,簡直就是學院派的典范。所以這期周刊,我們就重點引入的函數式編程,淺入淺出,一窺函數式編程的思想,可能讓你對編程語言的理解更加融會貫通一些。但從根本上來說,函數式編程就是關于如使用通用的可復用函數進行組合編程。 showImg(https://segmentfault.com/img/bVGQuc); 函數式編程(Functional Programming),一...

    csRyan 評論0 收藏0
  • 端到端測試神器 cypress 淺入淺出

    摘要:我之前寫過關于的文章,,最近在工作中用到比較多了,頓時覺得確實是比較優秀的一個。 我之前寫過關于cypress的文章,https://segmentfault.com/a/11...,最近在工作中用到cypress比較多了,頓時覺得cypress確實是比較優秀的一個。 1. 軟件安裝. 2. 安裝cypress 安裝cypress客戶端:http://download.cypress...

    CarlBenjamin 評論0 收藏0
  • vuex淺入淺出

    摘要:來自不同視圖的行為需要變更同一狀態。圖解后端的行為,響應在上的用戶輸入導致的狀態變化。中的非常類似于事件每個都有一個字符串的事件類型和一個回調函數。 什么是Vuex? Vuex 是一個專為 Vue.js 應用程序開發的狀態管理模式。它采用集中式存儲管理應用的所有組件的狀態,并以相應的規則保證狀態以一種可預測的方式發生變化。 Vuex采用和Redux類似的單向數據流的方式來管理數據。用戶...

    琛h。 評論0 收藏0
  • 淺入淺出FlowDroid(一): 簡介&基本使用

    摘要:后文將圍繞做一些介紹。盡管如此,的使用對新手而言仍然充滿了困難。本系列文章基本為個人見解,難免有錯誤與誤解,如有客觀錯誤歡迎提出。 前言 說到Android的污點分析框架,網上的搜索結果大多指向靜態的FlowDroid與動態的TaintDroid。盡管由于加固、混淆等技術使得針對Android的靜態分析越來越困難,但靜態分析的無先驗分析能力無法被動態分析取代,使得靜態分析仍有發揮空間。...

    wqj97 評論0 收藏0

發表評論

0條評論

最新活動
閱讀需要支付1元查看
<