欧美精品在线一区二区三区_亚洲女同精品视频_日韩一区免费_国产欧美久久久精品免费_国产这里只有精品_僵尸再翻生在线观看_久久99精品国产一区二区三区_亚洲免费一区二区_女教师淫辱の教室蜜臀av软件_中文字幕国产一区二区

如何讀懂并寫出裝逼的函數式代碼

2016-10-25    藍藍設計的小編

如果您想訂閱本博客內容,每天自動發到您的郵箱中, 請點這里

 

今天在微博上看到了 有人分享了下面的這段函數式代碼,我把代碼貼到下面,不過我對原來的代碼略有改動,對于函數式的版本,咋一看,的確令人非常費解,仔細看一下,你可能就暈掉了,似乎完全就是天書,看上去非常裝逼,哈哈。不過,我感覺解析那段函數式的代碼可能會一個比較有趣過程,而且,我以前寫過一篇《函數式編程》的入門式的文章,正好可以用這個例子,再升華一下原來的那篇文章,順便可以向大家更好的介紹很多基礎知識,所以寫下這篇文章。


先看代碼

這個代碼平淡無奇,就是從一個數組中找到一個數,O(n)的算法,找不到就返回 null。

下面是正常的 old-school 的方式。不用多說。

//正常的版本 function find (x, y) { for ( let i = 0; i < x.length; i++ ) { if ( x[i] == y ) return i;
  } return null;
} let arr = [0,1,2,3,4,5] console.log(find(arr, 2)) console.log(find(arr, 8))

結果到了函數式成了下面這個樣子(好像上面的那些代碼在下面若影若現,不過又有點不太一樣,為了消掉if語言,讓其看上去更像一個表達式,動用了 ? 號表達式):

//函數式的版本 const find = ( f => f(f) ) ( f =>
  (next => (x, y, i = 0) =>
    ( i >= x.length) ? null :
      ( x[i] == y ) ? i :
        next(x, y, i+1))((...args) =>
          (f(f))(...args)))

let arr = [0,1,2,3,4,5]
console.log(find(arr, 2))
console.log(find(arr, 8))

為了講清這個代碼,需要先補充一些知識。

Javascript的箭頭函數

首先先簡單說明一下,ECMAScript2015 引入的箭頭表達式。箭頭函數其實都是匿名函數,其基本語法如下:

(param1, param2, …, paramN) => { statements } 
(param1, param2, …, paramN) => expression // 等于 :  => { return expression; }  // 只有一個參數時,括號才可以不加: (singleParam) => { statements }
singleParam => { statements } //如果沒有參數,就一定要加括號: () => { statements }

下面是一些示例:

var simple = a => a > 15 ? 15 : a; 
simple(16); // 15 simple(10); // 10 let max = (a, b) => a > b ? a : b; // Easy array filtering, mapping, ... var arr = [5, 6, 13, 0, 1, 18, 23]; var sum = arr.reduce((a, b) => a + b); // 66 var even = arr.filter(v => v % 2 == 0); // [6, 0, 18] var double = arr.map(v => v * 2); // [10, 12, 26, 0, 2, 36, 46]

看上去不復雜吧。不過,上面前兩個 simple 和 max 的例子都把這箭頭函數賦值給了一個變量,于是它就有了一個名字。有時候,某些函數在聲明的時候就是調用的時候,尤其是函數式編程中,一個函數還對外返回函數的時候。比如下在這個例子:

function MakePowerFn(power) { return function PowerFn(base) { return Math.pow(base, power);
  } 
}

power3 = MakePowerFn(3); //制造一個X的3次方的函數 power2 = MakePowerFn(2); //制造一個X的2次方的函數 console.log(power3(10)); //10的3次方 = 1000 console.log(power2(10)); //10的2次方 = 100

其實,在 MakePowerFn 函數里的那個 PowerFn 根本不需要命名,完全可以寫成:

function MakePowerFn(power) { return function(base) { return Math.pow(base, power);
  } 
}

如果用箭頭函數,可以寫成:

MakePowerFn = power  => { return base => { return Math.pow(base, power);
  } 
}

我們還可以寫得更簡潔(如果用表達式的話,就不需要 { 和 }, 以及 return 語句 ):

MakePowerFn = power => base => Math.pow(base, power)

我還是加上括號,和換行可能會更清楚一些:

MakePowerFn = (power) => ( (base) => (Math.pow(base, power))
)

好了,有了上面的知識,我們就可以進入一個更高級的話題——匿名函數的遞歸。

匿名函數的遞歸

函數式編程立志于用函數表達式消除有狀態的函數,以及for/while循環,所以,在函數式編程的世界里是不應該用for/while循環的,而要改用遞歸(遞歸的性能很差,所以,一般是用尾遞歸來做優化,也就是把函數的計算的狀態當成參數一層一層的往下傳遞,這樣語言的編譯器或解釋器就不需要用函數棧來幫你保存函數的內部變量的狀態了)。

好了,那么,匿名函數的遞歸該怎么做?

一般來說,遞歸的代碼就是函數自己調用自己,比如我們求階乘的代碼:

function fact(n){ return n==0 ? 1 :  n * fact(n-1);
};
result = fact(5);

在匿名函數下,這個遞歸該怎么寫呢?對于匿名函數來說,我們可以把匿名函數當成一個參數傳給另外一個函數,因為函數的參數有名字,所以就可以調用自己了。 如下所示:

function combinator(func) { func(func);
}

這個是不是有點作弊的嫌疑?Anyway,我們再往下,把上面這個函數整成箭頭函數式的匿名函數的樣子。

func) => (func(func))

現在你似乎就不像作弊了吧。把上面那個求階乘的函數套進來是這個樣子:

首先,先重構一下fact,把fact中自己調用自己的名字去掉:

function fact(func, n) { return n==0 ? 1 :  n * func(func, n-1);
}

fact(fact, 5); //輸出120

然后,我們再把上面這個版本變成箭頭函數的匿名函數版:

var fact = (func, n) => ( n==0 ? 1 :  n * func(func, n-1) )
fact(fact, 5)

這里,我們依然還要用一個fact來保存這個匿名函數,我們繼續,我們要讓匿名函數聲明的時候,就自己調用自己。

也就是說,我們要把

(func, n) => ( n==0 ? 1 :  n * func(func, n-1) )

這個函數當成調用參數,傳給下面這個函數:

(func, x) => func(func, x)

最終我們得到下面的代碼:

( (func, x) => func(func, x) ) ( //函數體 (func, n) => ( n==0 ? 1 :  n * func(func, n-1) ), //第一個調用參數 5 //第二調用參數 );

好像有點繞,anyway, 你看懂了嗎?沒事,我們繼續。

動用高階函數的遞歸

但是上面這個遞歸的匿名函數在自己調用自己,所以,代碼中有hard code的實參。我們想實參去掉,如何去掉呢?我們可以參考前面說過的那個 MakePowerFn 的例子,不過這回是遞歸版的高階函數了。

HighOrderFact = function(func){ return function(n){ return n==0 ? 1 : n * func(func)(n-1);
  };
};

我們可以看,上面的代碼簡單說來就是,需要一個函數做參數,然后返回這個函數的遞歸版本。那么,我們怎么調用呢?

fact = HighOrderFact(HighOrderFact);
fact(5);

連起來寫就是:

HighOrderFact ( HighOrderFact ) ( 5 )

但是,這樣讓用戶來調用很不爽,所以,以我們一個函數把 HighOrderFact ( HighOrderFact ) 給代理一下:

fact = function ( hifunc ) { return hifunc ( hifunc );
} ( //調用參數是一個函數 function (func) { return function(n){ return n==0 ? 1 : n * func(func)(n-1);
    };
  }
);

fact(5); //于是我們就可以直接使用了

用箭頭函數重構一下,是不是簡潔了一些?

fact = (highfunc => highfunc ( highfunc ) ) ( func => n => n==0 ? 1 : n * func(func)(n-1)
);

上面就是我們最終版的階乘的函數式代碼。

回顧之前的程序

我們再來看那個查找數組的正常程序:

//正常的版本 function find (x, y) { for ( let i = 0; i < x.length; i++ ) { if ( x[i] == y ) return i;
  } return null;
}

先把for干掉,搞成遞歸版本:

function find (x, y, i=0) { if ( i >= x.length ) return null; if ( x[i] == y ) return i; return find(x, y, i+1);
}

然后,寫出帶實參的匿名函數的版本(注:其中的if代碼被重構成了 ?號表達式):

( (func, x, y, i) => func(func, x, y, i) ) ( //函數體 (func, x, y, i=0) => (
      i >= x.length ?  null :
         x[i] == y  ?  i : func (func, x, y, i+1) ), //第一個調用參數 arr, //第二調用參數 2 //第三調用參數 )

最后,引入高階函數,去除實參:

const find = ( highfunc => highfunc( highfunc ) ) ( func => (x, y, i = 0) => (
     i >= x.length ?  null :
           x[i] == y  ?  i : func (func) (x, y, i+1)
   )
);

注:函數式編程裝逼時一定要用const字符,這表示我寫的函數里的狀態是 immutable 的,天生驕傲!

再注:我寫的這個比原來版的那個簡單了很多,原來版本的那個又在函數中套了一套 next, 而且還動用了不定參數,當然,如果你想裝逼裝到天上的,理論上來說,你可以套N層,呵呵。

現在,你可以體會到,如此逼裝的是怎么來的了吧?

其它

你還別說這就是裝逼,簡單來說,我們可以使用數學的方式來完成對復雜問題的描述,那怕是遞歸。其實,這并不是新鮮的東西,這是Alonzo Church 和 Haskell Curry 上世紀30年代提出來的東西,這個就是 Y Combinator 的玩法,關于這個東西,你可以看看下面兩篇文章:《The Y Combinator (Slight Return)》,《Wikipedia: Fixed-point combinator》

 

藍藍設計www.ocunn.cn )是一家專注而深入的界面設計公司,為期望卓越的國內外企業提供卓越的UI界面設計BS界面設計  cs界面設計  ipad界面設計  包裝設計  圖標定制  用戶體驗 、交互設計、 網站建設 平面設計服務 

 

日歷

鏈接

個人資料

藍藍設計的小編 http://www.ocunn.cn

存檔

九九九九九伊人| 亚洲视频1区2区| 91福利在线观看| 久久久精品美女| 欧美不卡三区| 无码人妻久久一区二区三区蜜桃| av黄色在线播放| 91在线看片| 欧美日韩精品一区二区三区在线观看| 日韩高清一区二区| 亚洲成人av中文| www.日韩系列| 日韩一本精品| 国产又黄又粗又猛又爽的视频| 中文字幕+乱码+中文乱码91| av免费在线网站| 国产一区二区三区网| 成人性生交大片免费看视频在线| 欧美性大战xxxxx久久久| 欧美激情一区二区三区成人 | 97精品免费视频| 中文字幕久精品免| 一色道久久88加勒比一| 天天射,天天干| 色综合视频一区二区三区44| 蜜乳av另类精品一区二区| 亚洲一区免费观看| 欧美国产日本高清在线| 最近看过的日韩成人| 91视频免费看片| 中午字幕在线观看| 日韩一二三区| 国产成人av电影| 欧美一区二区福利在线| 成人性生交大片免费看小说| 日韩一区二区三区久久| 波多野结衣高清在线| 金瓶狂野欧美性猛交xxxx| 亚洲区综合中文字幕日日| 国产精品久久久久久久浪潮网站| 一区二区三区视频在线| 特级西西444www大精品视频| 午夜时刻免费入口| 天堂av在线资源| 天堂99x99es久久精品免费| 成人白浆超碰人人人人| 亚洲国产成人一区| 久久久久欧美| 蜜桃无码一区二区三区| 一本大道香蕉久在线播放29| 久久久一本精品99久久精品| avav在线播放| 日韩高清免费av| tube8在线hd| 国产日韩欧美一区在线| 一本久久综合亚洲鲁鲁五月天 | 亚洲久久在线| 色一情一乱一乱一91av| 国产女人18毛片水18精品| 日韩在线一区视频| 丰满人妻熟女aⅴ一区| 中文字幕视频精品一区二区三区| 白白色 亚洲乱淫| 亚洲人成网站在线播| 亚洲在线视频一区二区| 国产亚洲欧美精品久久久久久 | 一级成人国产| 欧美午夜精品电影| 亚洲自拍偷拍第一页| 日本免费福利视频| 你懂的在线观看| 伊人久久大香线| 欧美日韩中文字幕综合视频| 国产精品一区二区久久久久| 日韩大尺度视频| 在线免费观看你懂的| 蜜乳av综合| 一区二区三区在线观看网站| 91精品国产91久久久| 国产喷水theporn| 亚洲精品97久久中文字幕| 欧美网色网址| 亚洲男人电影天堂| 欧美激情第6页| 黄色免费视频大全| www.日韩在线观看| 日韩高清成人在线| 亚洲卡通动漫在线| 国产欧美久久一区二区| 亚洲AV无码国产精品| 成人av毛片| 国产日韩欧美一区在线| 欧美成人在线直播| 在线综合视频网站| 亚洲中文一区二区| 一区中文字幕| 国产精品久久久久天堂| 国产精品88a∨| 亚洲一区二区三区四区五区六区 | 国精品人妻无码一区二区三区喝尿 | 欧美日韩激情视频一区二区三区| 91超碰国产精品| 欧美日韩一卡二卡| 日本高清视频一区二区三区| 男人天堂中文字幕| 色成人综合网| 国产精品污网站| 国产精品老女人视频| 在线观看日韩精品视频| 菠萝菠萝蜜在线观看| 久久电影国产免费久久电影| 国产小视频国产精品| 中文字幕乱码人妻综合二区三区| 2222www色视频在线观看| 午夜精品毛片| 538prom精品视频线放| 在线视频一区观看| 一本一道人人妻人人妻αv| 日本在线中文字幕一区| 欧美日韩中文字幕综合视频| 精品国产免费人成电影在线观... 精品国产免费久久久久久尖叫 | 中文字幕免费精品| 欧美精品精品一区| 在线观看18视频网站| 亚洲黄色小说网| 国产精品豆花视频| 精品日产卡一卡二卡麻豆| 免费看欧美黑人毛片| 性感美女一级片| 雨宫琴音一区二区在线| 精品亚洲国产成av人片传媒 | 国产精品99一区二区三| 日韩精品一区二区三区视频| 国产69精品久久久久久久| 免费看成年人视频在线观看| 国产欧美三级| 综合激情国产一区| 日本久久久久久久久久| 都市激情久久综合| 久久天堂av综合合色蜜桃网| 国产欧美va欧美va香蕉在| 99视频只有精品| 中文在线免费一区三区| 色94色欧美sute亚洲线路一ni| 一区二区不卡在线| 天堂在线视频免费观看| 亚洲少妇在线| 久久色精品视频| 中文字幕影片免费在线观看| 亚洲综合电影| 亚洲精品第1页| 欧美亚洲免费高清在线观看| 国产黄a三级三级看三级| 黄色亚洲免费| 久久久国产精品免费| theav精尽人亡av| 国产极品一区| 日韩欧美国产骚| www国产免费| 视频国产在线观看| 国产成人免费视频网站| 国产精品久久久久久久美男| 国产乡下妇女做爰毛片| 久久不卡国产精品一区二区| 欧美tk丨vk视频| 污污视频网站在线| 在线天堂中文资源最新版| 亚洲精品少妇30p| 亚洲不卡一卡2卡三卡4卡5卡精品| 国产日韩欧美一区二区东京热 | 粉嫩av一区二区| 欧美高清视频不卡网| 不卡av免费在线| 91精选在线| 国产精品情趣视频| 欧美一区二区福利| 无码精品人妻一区二区三区影院| 蜜臀av一区二区在线免费观看| 国产91精品视频在线观看| 日本免费一二三区| 91不卡在线观看| 日韩中文字幕网站| 一级片黄色录像| 日本欧美三级| 亚洲精品一区二区网址| 又黄又爽的网站| www欧美在线观看| 91精品国产日韩91久久久久久| jizz大全欧美jizzcom| 瑟瑟视频在线看| 欧美日韩亚洲一区二| 男女猛烈激情xx00免费视频| 黄网址在线观看| 亚洲日本在线a| 欧美a级黄色大片| 成年人视频免费在线观看| 欧美国产综合一区二区| 亚洲欧美久久久久一区二区三区| 污视频在线看操| 久久老女人爱爱| 日韩欧美亚洲日产国| 夜鲁很鲁在线视频| 中文欧美字幕免费| 美女在线免费视频| 成人午夜在线影视| 亚洲成人av在线电影| 免费av网址在线| 亚洲黄色免费看| 欧美午夜在线观看| 97超碰人人看| 精品国产欧美| 亚洲精品理论电影| 成人精品999| 国产欧美日韩免费观看| 中文字幕亚洲第一| 久久精品人妻一区二区三区| 精品成人国产| 国产精品9999| 国产成人免费看一级大黄| 国产麻豆视频一区二区| 精品国产一区二区三区免费 | 清纯唯美亚洲综合一区| 欧美超级乱淫片喷水| 成人免费看片98欧美| 美女久久一区| 99久久国产免费免费| 黄网站app在线观看大全免费视频| 久久午夜免费电影| www亚洲国产| а√在线天堂官网| 欧美日韩不卡在线| 好吊一区二区三区视频| 成人在线一区| 91av在线网站| 成人激情四射网| 久久亚区不卡日本| 天堂8在线天堂资源bt| 中文字幕在线直播| 日韩欧美中文字幕一区| 国产亚洲精品精品精品| 欧美性久久久| 成人在线激情视频| 在线看黄的网站| 亚洲精品网站在线观看| 91女神在线观看| 精品成人自拍视频| 美女国内精品自产拍在线播放| 日韩免费av网站| 国产成人精品免费| 国产免费xxx| 亚洲高清黄色| 亚洲美女av在线播放| 国产精品theporn动漫| 美国欧美日韩国产在线播放| 日本成人黄色| av午夜在线观看| 亚洲а∨天堂久久精品9966| 青青草偷拍视频| 蜜桃视频免费观看一区| 日韩一区不卡| 国产在线精彩视频| 欧美精品一区二区久久婷婷| 久久在线视频精品| 麻豆久久久久久| 一区二区av| 99久久婷婷国产综合精品首页| 亚洲欧洲日产国产网站| 日本中文字幕久久| av在线不卡网| 成熟老妇女视频| 精品少妇一区| 欧美最近摘花xxxx摘花| 美国成人av| 欧美日韩中文在线观看| 18禁裸乳无遮挡啪啪无码免费| 韩日视频一区| 久久久人人爽| 少妇视频在线观看| 国产亚洲精品久久久久动| 中文字幕精品无码亚| 久久色成人在线| 亚洲色图 在线视频| 国产一区99| 91在线网站视频| h网站久久久| 日韩经典中文字幕在线观看| 久久久精品免费看| 久久久久久电影| 亚洲综合av在线播放| 亚洲xxx拳头交| 国产视频99| 国模冰冰炮一区二区| 日韩午夜在线视频| 亚洲国产精品久久久久久久| 一级做a爱片久久| 国产jk精品白丝av在线观看| 日日噜噜夜夜狠狠视频欧美人 | 婷婷成人在线| 91在线色戒在线| 青青青国内视频在线观看软件| 日韩国产精品亚洲а∨天堂免| 日批视频免费观看| 亚洲欧洲另类国产综合| 亚洲av永久无码精品| 久久国产精品久久久久久电车| 亚洲无玛一区| 青草伊人久久| 国产成人亚洲精品| 黄视频网站在线| 亚洲欧美日韩天堂一区二区| 国产免费黄色大片| 午夜私人影院久久久久| 国产成人av免费在线观看| 丁香桃色午夜亚洲一区二区三区| 日本爱爱免费视频| 亚洲精品极品少妇16p| 日本日本精品二区免费| 国产精品无码久久久久| 欧美一级视频在线观看| 日本高清中文字幕在线| 亚洲免费成人av电影| 成 人 黄 色 片 在线播放| 欧美体内谢she精2性欧美| 欧美激情图片小说| 26uuu色噜噜精品一区二区| 久久久久久国产精品日本| 亚洲成人原创| 成人性做爰片免费视频| 天堂成人娱乐在线视频免费播放网站| 91麻豆蜜桃| 丁香婷婷久久| 国产精品网站视频| 福利影院在线看| 久久久久久香蕉网| 日本精品在线| 日韩有码视频在线| 久久精品色图| 亚洲精品视频网上网址在线观看 | 日韩a级大片| 高清国产在线一区| 国产精品xxx| 国产精品无av码在线观看| 中文字幕在线官网| 欧美中文在线视频| 在线āv视频| 久久人人爽人人爽人人片av高请| 999国产在线视频| 亚洲图片欧洲图片av| 尤物视频在线观看| 亚洲激情视频在线观看| 天天操天天干天天操| 欧美一二三区在线观看| 精品国产999久久久免费| 在线视频综合导航| 伊人精品一区二区三区| 色吊一区二区三区| 97精品人妻一区二区三区| 色综合中文字幕国产| 波多野结衣mp4| 欧美亚洲国产怡红院影院| 亚洲性猛交富婆| 欧美色videos| 亚洲怡红院av| 制服丝袜在线91| 色婷婷av一区二区三区之红樱桃| 欧美va天堂va视频va在线| 天堂网在线中文| 亚洲精品久久在线| 日本在线视频1区| 日韩在线欧美在线| 五月天婷婷在线视频| 欧美激情va永久在线播放| 日本高清在线观看视频| 69久久夜色精品国产7777| 中文字幕在线免费观看视频| 国产精品久久久久久久久久久不卡| 欧洲一区二区三区精品| 成人在线播放av| 91九色鹿精品国产综合久久香蕉| 久久精品国产精品国产精品污| 色婷婷久久久| 9l视频自拍9l视频自拍| 综合亚洲视频| aaa毛片在线观看| 麻豆免费精品视频| 亚洲男女在线观看| 国产三级一区二区| 黄色一级视频免费| 精品久久久国产| 国产女同91疯狂高潮互磨| 日韩久久久久久| 国产在线视频福利| 国模精品视频一区二区| 我爱我色成人网| 国产精品一区而去| 精品一区二区三区在线| 欧美成人三级在线视频| 免费黄网站欧美| 女人又爽又黄免费女仆| 1区2区3区精品视频|