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

資訊專欄INFORMATION COLUMN

嘗試在JavaScript中構建一個"Maybe"檢測器

bingo / 2852人閱讀

摘要:我的目的是確保所有引用的使用都是絕對安全的,編譯器會自動進行檢查。它導致了數不清的錯誤漏洞和系統崩潰,可能在之后年中造成了十億美元的損失。這個函數將使用一個表示我們希望進行轉換的函數參數,并返回一個包含轉換結果的新參數。

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

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

那十億美元級別的錯誤

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

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

我們使用的簡單方法可能是:

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

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

const a = {
    b: {}
};

// or

const a = {};

當這個時候我們調用了appendString函數時,整個宇宙將會爆炸的...

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

這個時候可能要我們對函數的傳參進行空檢查:

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

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

Maybe的基本用法

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

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

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

甚至使用一個簡單的工廠函數來創建我們的Maybe - 考慮到往后可能會添加更多的方法,我們將使用一個對象來定義它:

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

所以現在我們可以這樣做:

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

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

一切都很好,但到目前為止還不是很實用。編程是關于轉換數據的,所以我們需要一種改變我們的Maybe的方法 - 一個map函數。這個map函數將使用一個表示我們希望進行轉換的函數參數,并返回一個包含轉換結果的新參數。重要的是,如果maybe不包含任何內容,那么該函數將不會被應用,我們將返回一個新的maybe.nothing方法。

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

現在我們可以這樣來調用maybe實現:

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

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

關鍵一點的是maybe.map返回一個新的maybe,所以我們可以將這些操作鏈接在一起。回到我們現在可以做的最初的問題:

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

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

這里的好處是,如果鏈中的任何步驟返回null,我們仍然會得到結果Maybe.nothing的結果,而不是運行時錯誤。

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

它比Haskell的實現更加靈活,而且還附帶了一些額外的功能,考慮到
JavaScript的類型系統限制和語言的一般靈活性。

Point-free 鏈式函數

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

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

這里可以參考知乎上的JavaScript函數式編程(一)里面的知識點。

所以現在我們可以在我們的map鏈式中使用這個功能:

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

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

好了,我們現在終于到了這一步, 我們已經處理了空檢查,并將其重構為point-free形式。接下來需要做的就是使邏輯可重用性;我們想要的是能夠將我們的功能傳遞給一個功能,并應用所有步驟,以便我們可以在許多不同的Maybe上重新使用提取器:

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

我們需要的是一個需要我們的步驟的函數,并且每個步驟依次調用我們Maybe.map方法。我們將調用函數Maybe.chain,我們可以用reducer來實現:

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

我們現在可以構建一個可以應用于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()

雖然我在學習Elm之前不習慣Maybe的價值觀概念,但是他們在JavaScript中不想落后啊。如果我們簡簡單單地去使用它,就只會使用到基礎方法而已,所以我們要在它的基礎上添加更多的功能函數。所以我將在稍后閱讀關于使用Maybe的后續文章。

::完畢::

更多閱讀

Elm入門實踐(一)——基礎篇

函數式編程入門教程

JavaScript函數式編程(一)

JavaScript函數式編程(二)

JavaScript函數式編程(三)

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

A Maybe monad implementation in JavaScript

Functional Programming in Javascript

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

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

相關文章

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

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

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

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

    Fundebug 評論0 收藏0
  • MindsDB:一個利用企業數據構建 AI 的平臺

    MindsDB作為一個開源項目,它旨在將機器學習模型無縫集成到現有的數據庫系統中,為用戶提供實時的數據預測能力。這個項目的創新之處在于,它能夠以簡單、直觀的方式讓開發者和非技術人員都能夠利用AI進行數據分析和預測。 它是根據企業數據庫定制的AI平臺,使用者可以根據數據庫、矢量存儲和應用程序數據實時創建、提供和微調模型。簡介MindsDB 的核心理念是使數據庫不僅能夠存儲和檢索數據,還能基于這些數據...

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

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

    UCloud小助手 評論0 收藏0
  • 《HelloGitHub》第 68 期

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

    番茄西紅柿 評論0 收藏2637

發表評論

0條評論

bingo

|高級講師

TA的文章

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