成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

嘗試在JavaScript中構(gòu)建一個(gè)"Maybe"檢測(cè)器

bingo / 2853人閱讀

摘要:我的目的是確保所有引用的使用都是絕對(duì)安全的,編譯器會(huì)自動(dòng)進(jìn)行檢查。它導(dǎo)致了數(shù)不清的錯(cuò)誤漏洞和系統(tǒng)崩潰,可能在之后年中造成了十億美元的損失。這個(gè)函數(shù)將使用一個(gè)表示我們希望進(jìn)行轉(zhuǎn)換的函數(shù)參數(shù),并返回一個(gè)包含轉(zhuǎn)換結(jié)果的新參數(shù)。

翻譯原文出處:Building a Maybe in JavaScript
鄙人翻譯略差且略有出入,別見笑。

很多時(shí)候我們會(huì)碰到:Uncaught TypeError: Cannot read property "x" of undefined(無法讀取未定義的屬性“x”)。
我猜,如果你正好看到這個(gè)你以前不單只碰過還歷歷在目的東西,可能有那么一刻想把顯示器給砸了。
這里想起了我們尊敬的計(jì)算機(jī)領(lǐng)域的爵士——托尼·霍爾;他在Infoq辦的大會(huì)演講時(shí),用到的主題是:“Null References: The Billion Dollar Mistake”(Null 引用:一個(gè)十億美元級(jí)別的錯(cuò)誤),講演摘要中這樣寫的:
“我把Null引用稱為自己的十億美元錯(cuò)誤。它的發(fā)明是在1965年,那時(shí)我用一個(gè)面向?qū)ο笳Z言( ALGOL W )設(shè)計(jì)了第一個(gè)全面的引用類型系統(tǒng)。我的目的是確保所有引用的使用都是絕對(duì)安全的,編譯器會(huì)自動(dòng)進(jìn)行檢查。但是我未能抵御住誘惑,加入了Null引用,僅僅是因?yàn)閷?shí)現(xiàn)起來非常容易。它導(dǎo)致了數(shù)不清的錯(cuò)誤、漏洞和系統(tǒng)崩潰,可能在之后40年中造成了十億美元的損失。近年來,大家開始使用各種程序分析程序,比如微軟的PREfix和PREfast來檢查引用,如果存在為非Null的風(fēng)險(xiǎn)時(shí)就提出警告。更新的程序設(shè)計(jì)語言比如Spec#已經(jīng)引入了非Null引用的聲明。這正是我在1965年拒絕的解決方案。”

那十億美元級(jí)別的錯(cuò)誤

幸運(yùn)的是,我們可以使用一些功能性的編程技術(shù),以清潔、簡(jiǎn)潔和可靠的方式緩解這帶來疼痛。讓我們想象一下,我們要從下面的對(duì)象中提取屬性“c”的值,并附加字符串“is great”。

const a = {
    b: {
        c: "fp"
    }
};

我們使用的簡(jiǎn)單方法可能是:

const appendString = (obj) =>
    obj.b.c + " is great";
    
appendString(a);

這樣的寫法很棒,但可悲的是a對(duì)象并非是一成不變的。因此,我們收回的數(shù)據(jù)有時(shí)會(huì)采取到以下的形式:

const a = {
    b: {}
};

// or

const a = {};

當(dāng)這個(gè)時(shí)候我們調(diào)用了appendString函數(shù)時(shí),整個(gè)宇宙將會(huì)爆炸的...

無法讀取未定義的屬性“c”

這個(gè)時(shí)候可能要我們對(duì)函數(shù)的傳參進(jìn)行空檢查:

const appendString = (obj) => {
    if (!obj || !obj.b || !obj.b.c || !) return null;
    return obj.b.c + " is great";
}

這是有效的,但它看起來很丑陋和很容易出錯(cuò)。我們必須對(duì)傳參進(jìn)行每種類型的對(duì)象定義特定的(正確的)空檢查,這是不是很有趣(復(fù)雜)。
哈哈哈,這個(gè)時(shí)候可能Maybe就派得上場(chǎng)了。

Maybe的基本用法

基本上,我們都會(huì)將要構(gòu)建的對(duì)象封裝其值可能為null的概念,并且考慮到隨之而來的復(fù)雜性。在學(xué)習(xí)Elm(一門專注于Web前端的純函數(shù)式語言)之后,我會(huì)在Maybe上的封裝了兩個(gè)概念狀態(tài)Maybe.justMaybe.nothing。對(duì)于初學(xué)者,我們簡(jiǎn)單地定義一個(gè)返回一個(gè)布爾值的isNothing方法,告訴我們Maybe是否不包含任何內(nèi)容:

const isNullOrUndef = (value) => value === null || typeof value === "undefined";

const maybe = (value) => ({
    isNothing: () => isNullOrUndef(value)
});

甚至使用一個(gè)簡(jiǎn)單的工廠函數(shù)來創(chuàng)建我們的Maybe - 考慮到往后可能會(huì)添加更多的方法,我們將使用一個(gè)對(duì)象來定義它:

const Maybe = {
    just: maybe,
    nothing: () => maybe(null)
};

所以現(xiàn)在我們可以這樣做:

const maybeNumberOne = Maybe.just("a value");
const maybeNumberTwo = Maybe.nothing();

maybeNumberOne.isNothing(); // false
maybeNumberTwo.isNothing(); // true

一切都很好,但到目前為止還不是很實(shí)用。編程是關(guān)于轉(zhuǎn)換數(shù)據(jù)的,所以我們需要一種改變我們的Maybe的方法 - 一個(gè)map函數(shù)。這個(gè)map函數(shù)將使用一個(gè)表示我們希望進(jìn)行轉(zhuǎn)換的函數(shù)參數(shù),并返回一個(gè)包含轉(zhuǎn)換結(jié)果的新參數(shù)。重要的是,如果maybe不包含任何內(nèi)容,那么該函數(shù)將不會(huì)被應(yīng)用,我們將返回一個(gè)新的maybe.nothing方法。

const maybe = (value) => ({
    isNothing: () => isNullOrUndef(value),
    map: (transformer) => !isNullOrUndef(value) ? Maybe.just(transformer(value)) : Maybe.nothing()
});

現(xiàn)在我們可以這樣來調(diào)用maybe實(shí)現(xiàn):

const maybeOne = Maybe.just(5);
maybeOne.map(x => x + 1); // Maybe.just(6);

const maybeTwo = Maybe.nothing();
maybeTwo.map(x => x + 1) // Maybe.nothing();

關(guān)鍵一點(diǎn)的是maybe.map返回一個(gè)新的maybe,所以我們可以將這些操作鏈接在一起?;氐轿覀儸F(xiàn)在可以做的最初的問題:

const a = {
    b: {
        c: "fp"
    }
};

const maybeA = Maybe.just(a)
    .map(a => a.b)
    .map(b => b.c)
    .map(c => c + " is great!");

這里的好處是,如果鏈中的任何步驟返回null,我們?nèi)匀粫?huì)得到結(jié)果Maybe.nothing的結(jié)果,而不是運(yùn)行時(shí)錯(cuò)誤。

好了,在Github上面有個(gè)maybe.js庫: A Maybe monad implementation in JavaScript:

它比Haskell的實(shí)現(xiàn)更加靈活,而且還附帶了一些額外的功能,考慮到
JavaScript的類型系統(tǒng)限制和語言的一般靈活性。

Point-free 鏈?zhǔn)胶瘮?shù)

如果你看過我以前發(fā)布的文章柯里化函數(shù),那么你就會(huì)想我們可以弄得比這更好。我們可以創(chuàng)建從對(duì)象中提取命名屬性的高階函數(shù),以及用于追加字符串:

const prop = (propName) => (obj) => obj[propName];
const append = (appendee) => (appendix) = appendee + appendix;

這里可以參考知乎上的JavaScript函數(shù)式編程(一)里面的知識(shí)點(diǎn)。

所以現(xiàn)在我們可以在我們的map鏈?zhǔn)街惺褂眠@個(gè)功能:

const a = {
    b: {
        c: "fp"
    }
};

const maybeA = Maybe.just(a)
    .map(prop("b"))
    .map(prop("c"))
    .map(append(" is great!"));

好了,我們現(xiàn)在終于到了這一步, 我們已經(jīng)處理了空檢查,并將其重構(gòu)為point-free形式。接下來需要做的就是使邏輯可重用性;我們想要的是能夠?qū)⑽覀兊墓δ軅鬟f給一個(gè)功能,并應(yīng)用所有步驟,以便我們可以在許多不同的Maybe上重新使用提取器:

   const extractor = // what we"re about to make
    extractor(Maybe.just(a)); // Maybe.just("fp is great")

我們需要的是一個(gè)需要我們的步驟的函數(shù),并且每個(gè)步驟依次調(diào)用我們Maybe.map方法。我們將調(diào)用函數(shù)Maybe.chain,我們可以用reducer來實(shí)現(xiàn):

const Maybe = {
    just: maybe,
    nothing: () => maybe(null),
    chain: (...fns) => (input) => fns.reduce((output, curr) => output.map(curr), input)
};

我們現(xiàn)在可以構(gòu)建一個(gè)可以應(yīng)用于maybe的可用功能:

const appendToC = Maybe.chain(
    prop("b"),
    prop("c"),
    append(" is great!")
);

并將其用于各種輸入:

const goodInput = Maybe.just({
    b: {
        c: "fp"
    }
});

const badInput = Maybe.just({});

appendToC(goodInput); // Maybe.just("fp is great!")
appendToC(badInput); // Maybe.nothing()

雖然我在學(xué)習(xí)Elm之前不習(xí)慣Maybe的價(jià)值觀概念,但是他們?cè)贘avaScript中不想落后啊。如果我們簡(jiǎn)簡(jiǎn)單單地去使用它,就只會(huì)使用到基礎(chǔ)方法而已,所以我們要在它的基礎(chǔ)上添加更多的功能函數(shù)。所以我將在稍后閱讀關(guān)于使用Maybe的后續(xù)文章。

::完畢::

更多閱讀

Elm入門實(shí)踐(一)——基礎(chǔ)篇

函數(shù)式編程入門教程

JavaScript函數(shù)式編程(一)

JavaScript函數(shù)式編程(二)

JavaScript函數(shù)式編程(三)

函數(shù)式JavaScript(2):如何打造“函數(shù)式”編程語言?

A Maybe monad implementation in JavaScript

Functional Programming in Javascript

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

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/85182.html

相關(guān)文章

  • React:"don't fuck it up like Google did

    摘要:核心開發(fā)人員大神在開了個(gè),用來征詢社區(qū)對(duì)的建議。而且的工程師并沒有因此止步,他們?cè)谖臋n中又告訴開發(fā)者,不僅僅要把寫到中,也應(yīng)該寫到中。無論怎么使用自定義語法,也不應(yīng)該影響這種好處,即使最終實(shí)現(xiàn)看起來有一些怪異。 React 核心開發(fā)人員 sebmarkbage 大神在 GitHub 開了個(gè) issues,用來征詢社區(qū)對(duì) JSX 2.0 的建議。 showImg(https://segm...

    Cristalven 評(píng)論0 收藏0
  • Google推出的爬蟲新神器:Pyppeteer,神擋殺神,佛擋殺佛!

    摘要:注意,是叫做,不是。兩款瀏覽器同根同源,它們有著同樣的,但配色不同,由藍(lán)紅綠黃四種顏色組成,而由不同深度的藍(lán)色構(gòu)成。另外是基于的新特性實(shí)現(xiàn)的,所以它的一些執(zhí)行也支持異步操作,效率相對(duì)于來說也提高了。是否響應(yīng)信號(hào),一般是命令,默認(rèn)是。 如果大家對(duì) Python 爬蟲有所了解的話,想必你應(yīng)該聽說過 Selenium 這個(gè)庫,這實(shí)際上是一個(gè)自動(dòng)化測(cè)試工具,現(xiàn)在已經(jīng)被廣泛用于網(wǎng)絡(luò)爬蟲中來應(yīng)對(duì) ...

    Fundebug 評(píng)論0 收藏0
  • MindsDB:一個(gè)利用企業(yè)數(shù)據(jù)構(gòu)建 AI 的平臺(tái)

    MindsDB作為一個(gè)開源項(xiàng)目,它旨在將機(jī)器學(xué)習(xí)模型無縫集成到現(xiàn)有的數(shù)據(jù)庫系統(tǒng)中,為用戶提供實(shí)時(shí)的數(shù)據(jù)預(yù)測(cè)能力。這個(gè)項(xiàng)目的創(chuàng)新之處在于,它能夠以簡(jiǎn)單、直觀的方式讓開發(fā)者和非技術(shù)人員都能夠利用AI進(jìn)行數(shù)據(jù)分析和預(yù)測(cè)。 它是根據(jù)企業(yè)數(shù)據(jù)庫定制的AI平臺(tái),使用者可以根據(jù)數(shù)據(jù)庫、矢量存儲(chǔ)和應(yīng)用程序數(shù)據(jù)實(shí)時(shí)創(chuàng)建、提供和微調(diào)模型。簡(jiǎn)介MindsDB 的核心理念是使數(shù)據(jù)庫不僅能夠存儲(chǔ)和檢索數(shù)據(jù),還能基于這些數(shù)據(jù)...

    UCloud小助手 評(píng)論0 收藏0
  • OpenAI開發(fā)ChatGPT“反作弊神器”,99.9%超高命率,好消息:還沒上線

    檢查內(nèi)容是否用了ChatGPT,準(zhǔn)確率高達(dá)99.9%!OpenAI又左右互搏上了,給AI生成的文本打水印,高達(dá)99.9%準(zhǔn)確率抓「AI槍手」作弊代寫。其能夠精準(zhǔn)識(shí)別出論文或研究報(bào)告是否由ChatGPT撰寫,甚至能追溯其使用的具體時(shí)間點(diǎn)。它能專門用來檢測(cè)是否用ChatGPT水了論文/作業(yè)。早在2022年11月(ChatGPT發(fā)布同月)就已經(jīng)提出想法了。但是!這么好用的東西,卻被內(nèi)部雪藏了2年,現(xiàn)在都...

    UCloud小助手 評(píng)論0 收藏0
  • 《HelloGitHub》第 68 期

    摘要:整個(gè)項(xiàng)目簡(jiǎn)單還具有實(shí)用價(jià)值,可作為的實(shí)戰(zhàn)項(xiàng)目學(xué)習(xí)的調(diào)試工具欄。查看文檔自動(dòng)在個(gè)人首頁展示編程時(shí)長的工具。通過學(xué)習(xí)這些前沿的人工智能論文,提前了解在未來更多可能性可以將圖片和視頻轉(zhuǎn)換成漫畫風(fēng)格的工具。興趣是最好的老師,HelloGitHub 讓你對(duì)編程感興趣!簡(jiǎn)介HelloGitHub 分享 GitHub 上有趣、入門級(jí)的開源項(xiàng)目。https://github.com/521xueweihan...

    番茄西紅柿 評(píng)論0 收藏2637

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<