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

資訊專欄INFORMATION COLUMN

[譯]函數(shù)式JavaScript之Functors

zone / 2433人閱讀

摘要:在我們上面的例子里,的輸入和返回值是一樣的數(shù)據(jù)類型,都是。所以我們可以寫一個服務(wù)于函數(shù)的么答案是肯定的但怎么拆開一個函數(shù)是個問題簡單點兒,你可以直接執(zhí)行這個函數(shù),然后用她的返回值。我們來拿試一下聲明了一個函數(shù)的參數(shù)及返回值的形態(tài)。

Functors

先看看如下代碼:

function plus1(value) {  
    return value + 1;
}

這就是一個普通函數(shù),接收一個integer作為參數(shù),再加1返回。類似的,我們還能再來一個加2的函數(shù)。稍后我們會用到這幾個函數(shù):

function plus2(value) {  
    return value + 2;
}

下面我們來寫一個如下的組合函數(shù),來按需執(zhí)行上述函數(shù)

function F(value, fn) {  
    return fn(value);
}

F(1, plus1) ==>> 2

當傳入正確的integer參數(shù)時,這個組合函數(shù)F工作正常,那如果傳入的數(shù)據(jù)類型是Array呢?

F([1, 2, 3], plus1)   ==>> "1,2,31"

我擦,我們給了一個Array of integers,想讓她們和plus1中的數(shù)值相加,結(jié)果返回的是個string?!結(jié)果不對不說,我們是以Array開頭兒的,結(jié)果返回一個string,類型也沒對上啊!換句話說,我們這個程序把輸入的結(jié)構(gòu)也給整岔劈了。我們還是希望函數(shù)F能做“正確的事兒”-維護輸入?yún)?shù)的數(shù)據(jù)結(jié)構(gòu),并使其被各handler正確處理。

OK,我這兒說的“維護輸入?yún)?shù)的數(shù)據(jù)結(jié)構(gòu)”是?這個函數(shù)F應(yīng)該把傳入的Array拆開并得到其中的每一個值。然后依次交給handler處理。然后把handler處理后的各個結(jié)果再封裝成一個新的Array,然后返回這個新Array。好消息是我這一堆廢話說的東西都不用你寫了,JavaScript已經(jīng)寫好這么一個函數(shù)了,她叫map

[1, 2, 3].map(plus1)   ==>> [2, 3, 4]

map就是一個functor

functor就是一個函數(shù),接收一個數(shù)值、一個handler,然后做事兒!

再說細點兒

functor就是一個函數(shù),接收一個數(shù)值、一個handler,拆開傳入的原始值,得到其中的各個分解后的值,然后調(diào)用handler依次處理每一個上一步的到的數(shù)據(jù),再將處理后的多個數(shù)據(jù)再封裝成一個新的結(jié)構(gòu)體,最后返回這個新的結(jié)構(gòu)體。

這里要注意傳入值的類型,拆開后的各個數(shù)值可能是原始數(shù)據(jù)類型,也可能是集合。

而且,最后返回的數(shù)據(jù)類型也不必一定和傳入的數(shù)據(jù)類型一模一樣。在我們上面的例子里,map的輸入和返回值是一樣的數(shù)據(jù)類型,都是Array。返回的數(shù)據(jù)結(jié)構(gòu)可以是任意結(jié)構(gòu),只要能分別獲取其中的數(shù)值即可。所以,假設(shè)你有一個函數(shù),接收一個Array作為參數(shù),但返回一個包含了keysObject,每個key都指向一個對應(yīng)的數(shù)值,那這也是一個functor

JavaScript里,filter就是一個functor,因為她依舊返回一個Array,但forEach就不是,因為她返回undefined。這就是我們說的,forEach沒有“維護輸入?yún)?shù)的數(shù)據(jù)結(jié)構(gòu)”。

Functors是數(shù)學(xué)里關(guān)于"homomorphisms between categories"的概念,不懂沒關(guān)系,我們分別換個詞兒再讀一下:

homo = 一些、多個

morphisms = 維護數(shù)據(jù)結(jié)構(gòu)的函數(shù)

category = 類型

根據(jù)上述詞匯分析,函數(shù)F可以看作是兩個普通函數(shù)fg的組合。

F(f . g) = F(f) . F(g)

其中.就是表示組合。即:functors必須保存組合特性。

基于這個方程式,我們就能得出一個函數(shù)是否是functor的結(jié)論。

Array Functor

剛才我們看到map就是一個操作Arrayfunctor。下面我們來證明一下Array.map就是一個functor

function compose(f, g) {
    return function(x) {
        return f(g(x));
    };
}

組合多個函數(shù)就是通過將前一個函數(shù)的執(zhí)行結(jié)果傳給后一個函數(shù)作為參數(shù)的形式來依次調(diào)用多個函數(shù)。注意:我們上面這個compose是從右向左執(zhí)行的,將g的執(zhí)行結(jié)果傳給f

[1, 2, 3].map(compose(plus1, plus2))   ==>> [ 4, 5, 6 ]

[1, 2, 3].map(plus2).map(plus1)        ==>> [ 4, 5, 6 ]

看看!隨你怎么寫,結(jié)果都一樣。 所以map就是一個functor

下面我們來試試其他functorsfunctors傳入?yún)?shù)的類型可以是任意類型,只要你有辦法拆開她的值,然后返回一個新的數(shù)據(jù)結(jié)構(gòu)。

String Functor

OK,那我們是不是也可以寫一個能處理stringfunctor

先來文個問題,你能“拆開”一個string么? 必須的呀(這里如果有疑問,就是你的不對了哦),如果你把一個string當成一個Array of chars,是不是可以拆開了?所以啊,問題就在于你是如何思考的。

然后,我們也知道每一個char其實都有一個integerchar code。那我都可以使用上面的plus1操作每一個char,然后將所有結(jié)果封裝回string,再返回!

function stringFunctor(value, fn) {  
    var chars = value.split("");
    return chars.map(function(char) {  
        return String.fromCharCode(fn(char.charCodeAt(0)));
    }).join("");
}

stringFunctor("ABCD", plus1) ==>> "BCDE"

開始感受到牛逼之處了么?估計你都能基于string functor寫一個XX解析器了。

Function Functor

JavaScript中,函數(shù)是一等公民(first class citizens)。意思是你可以像其他任何類型那樣使用函數(shù)。所以我們可以寫一個服務(wù)于函數(shù)的functor么?

答案是肯定的!

但怎么拆開一個函數(shù)是個問題!簡單點兒,你可以直接執(zhí)行這個函數(shù),然后用她的返回值。不過傻子也知道這肯定有問題(執(zhí)行是需要參數(shù)的)!切記這里我們一定要把傳入的函數(shù)本身當做那個傳入的“值”。明確了這一點,我們只要再返回一個函數(shù),看上去就是functor了吧?當這個返回的函數(shù)執(zhí)行時,我們傳入指定參數(shù),其實她內(nèi)部是將傳入的參數(shù)遞給value函數(shù),再將value(initial)的結(jié)果傳給fn,最后的到最終返回值。

function functionFunctor(value, fn) {
    return function(initial) {
        return function() {
            return fn(value(initial));
        };
    };
}

var init = functionFunctor(function(x) {return x * x}, plus1);
var final = init(2);
final() ==> 5

說白了,上面這個Function functor沒做什么特別的事。但要注意的是,除非你最終執(zhí)行該functor,否則什么事都不會發(fā)生哦!所有東西都被暫存起來,直到你執(zhí)行最終functor。由Function functor可以衍生出來其他函數(shù)式編程的內(nèi)容,譬如:狀態(tài)維護、連續(xù)調(diào)用甚至是Promise。有興趣的,可以自己嘗試根據(jù)已學(xué)知識來把這幾個概念實現(xiàn)一下。

MayBe Functor
function mayBe(value, fn) {
    return value === null || value === undefined ? value : fn(value);
}

看,這也是個合法的functor

mayBe(undefined, compose(plus1, plus2))     ==>> undefined
mayBe(mayBe(undefined, plus2), plus1)       ==>> undefined
mayBe(1, compose(plus1, plus2))             ==>> 4
mayBe(mayBe(1, plus2), plus1)               ==>> 4

mayBe通過了我們上面的測試。這兒還真沒有什么拆開和重新封裝。如果傳入是空,那返回也是空。mayBe是一中簡單有效的路徑選擇函數(shù),和一下這種寫法相同:

if (result === null) {
    return null;
} else {
    doSomething(result);
}
Identity Function
function id(x) {
    return x;
}

上面這個就是所謂的identity function。她就把傳入的參數(shù)又返回了一遍。她就是這么叫的,我也沒轍,因為在數(shù)學(xué)計算里,這就表示組合函數(shù)的ID。

前面我們學(xué)了functor就是要保存組合特性。其實functor也得保存她的identity

F(value, id) = value

我們來拿map試一下

[1, 2, 3].map(id)    ==>>  [ 1, 2, 3 ]
Type Signature

Type Signature聲明了一個函數(shù)的參數(shù)及返回值的形態(tài)。那之前我們寫的plus1函數(shù)的Type Signature就是:

f: int -> int

map作為functor,她的Type Signature依賴于handlerType Signature。譬如:mapplus1組合使用的話,她的Type Signature是:

map: [int] -> [int]

不過,由于handlerType Signature不必前后一致,如下:

f: int -> string

mapType Signature也可以是:

map: [int] -> [string]

這就是說,類型變化不會影響functor的函數(shù)組合特性。一般來說,functorType Signature可以這么定義:

F: A -> B

舉例說,就是map可以傳入數(shù)值數(shù)組,但是卻返回一個字符串數(shù)組,她依舊是functor

Monads是一種特殊類型的functor,定義如下:

M: A -> A

更多內(nèi)容,且看下回分解!

原文地址:Functional JavaScript - functors

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/78894.html

相關(guān)文章

  • 攻克前端javascript面試:什么是函數(shù)編程?

    摘要:僅在幾年以前,僅有少數(shù)的程序員知道函數(shù)式編程是什么。函數(shù)式編程是聲明性的而不是命令式的應(yīng)用狀態(tài)流經(jīng)純函數(shù)中。函數(shù)式編程是一種編程模式。在理解軟件是如何使用函數(shù)式編程構(gòu)建時,理解函數(shù)組合是非常重要的一步。不可變性是函數(shù)式編程的核心概念。 函數(shù)式編程已然變成了一個javascript語言中一個非常熱門的話題。僅在幾年以前,僅有少數(shù)的js程序員知道函數(shù)式編程是什么。但是在過去三年中,我所見過...

    wslongchen 評論0 收藏0
  • 】每個JavaScript 開發(fā)者應(yīng)該了解的10個面試題

    摘要:避免脆弱的基類問題。紅牌警告沒有提到上述任何問題。單向數(shù)據(jù)流意味著模型是單一的事實來源。單向數(shù)據(jù)流是確定性的,而雙向綁定可能導(dǎo)致更難以遵循和理解的副作用。原文地址 1. 你能說出兩種對 JavaScript 應(yīng)用開發(fā)者而言的編程范式嗎? 希望聽到: 2. 什么是函數(shù)編程? 希望聽到: 3. 類繼承和原型繼承的不同? 希望聽到 4. 函數(shù)式編程和面向?qū)ο缶幊痰膬?yōu)缺點? ...

    mykurisu 評論0 收藏0
  • 2017-06-27 前端日報

    摘要:前端日報精選漫談函數(shù)式編程一十年蹤跡的博客前端每周清單的優(yōu)勢與劣勢有望超越在嵌入式及物聯(lián)網(wǎng)的應(yīng)用現(xiàn)狀進階系列高階組件詳解一前端之路譯如何充分利用控制臺掘金程序猿升級攻略眾成翻譯中文譯如何充分利用控制臺掘金前端從強制開啟壓縮探 2017-06-27 前端日報 精選 漫談 JS 函數(shù)式編程(一) - 十年蹤跡的博客前端每周清單: Vue的優(yōu)勢與劣勢;Node.js有望超越Java;JS在嵌...

    Eidesen 評論0 收藏0
  • 正在失業(yè)中的《課多周刊》(第3期)

    摘要:正在失業(yè)中的課多周刊第期我們的微信公眾號,更多精彩內(nèi)容皆在微信公眾號,歡迎關(guān)注。若有幫助,請把課多周刊推薦給你的朋友,你的支持是我們最大的動力。是一種禍害譯本文淺談了在中關(guān)于的不好之處。淺談超時一運維的排查方式。 正在失業(yè)中的《課多周刊》(第3期) 我們的微信公眾號:fed-talk,更多精彩內(nèi)容皆在微信公眾號,歡迎關(guān)注。 若有幫助,請把 課多周刊 推薦給你的朋友,你的支持是我們最大的...

    robin 評論0 收藏0
  • 正在失業(yè)中的《課多周刊》(第3期)

    摘要:正在失業(yè)中的課多周刊第期我們的微信公眾號,更多精彩內(nèi)容皆在微信公眾號,歡迎關(guān)注。若有幫助,請把課多周刊推薦給你的朋友,你的支持是我們最大的動力。是一種禍害譯本文淺談了在中關(guān)于的不好之處。淺談超時一運維的排查方式。 正在失業(yè)中的《課多周刊》(第3期) 我們的微信公眾號:fed-talk,更多精彩內(nèi)容皆在微信公眾號,歡迎關(guān)注。 若有幫助,請把 課多周刊 推薦給你的朋友,你的支持是我們最大的...

    Joyven 評論0 收藏0

發(fā)表評論

0條評論

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