」工欲善其事,必先利其器。「—孔子《論語.錄靈公》
首頁 > 程式設計 > JavaScript 函數式程式設計簡介:Monad 與函式 #7

JavaScript 函數式程式設計簡介:Monad 與函式 #7

發佈於2024-07-29
瀏覽:425

Introduction to Functional Programming in JavaScript: Monad and functors #7

Monad 和函子是函數式程式設計中的高階概念,為處理資料轉換、副作用和組合提供了強大的抽象。雖然它們起源於數學範疇論,但它們在 JavaScript 等程式語言中具有實際應用。

什麼是函子?

函子是實現映射方法的資料類型,該方法將函數應用於函子內的值並傳回具有轉換後的值的新函子。本質上,函子允許您將函數應用於包裝值而不更改容器的結構。

函子的例子
class Box {
  constructor(value) {
    this.value = value;
  }

  map(fn) {
    return new Box(fn(this.value));
  }
}

// Usage
const box = new Box(2);
const result = box.map(x => x   3).map(x => x * 2);
console.log(result); // Box { value: 10 }

在此範例中,Box 是一個函子。 map 方法將函數 fn 應用於框內的值,並傳回一個具有轉換後的值的新框。

什麼是 Monad?

monad 是一種仿函數,它實作了兩個附加方法:of(或在某些語言中為 return)和 flatMap(也稱為 bind 或 chain)。 Monad 提供了一種對所包含的值進行鍊式操作的方法,同時維護 monad 的上下文。

單子的性質
  1. Unit (of):接受一個值並傳回包含該值的 monad 的方法。
  2. Bind (flatMap):一種方法,它採用傳回 monad 的函數並將其應用於所包含的值,從而展平結果。
單子的例子
class Box {
  constructor(value) {
    this.value = value;
  }

  static of(value) {
    return new Box(value);
  }

  map(fn) {
    return Box.of(fn(this.value));
  }

  flatMap(fn) {
    return fn(this.value);
  }
}

// Usage
const box = Box.of(2);
const result = box
  .flatMap(x => Box.of(x   3))
  .flatMap(x => Box.of(x * 2));
console.log(result); // Box { value: 10 }

在這個例子中,Box 既是一個函子又是一個 monad。 of 方法將值包裝在 Box 中,而 flatMap 方法將函數應用於所包含的值並傳回結果 monad。

Monad 和 Functor 的實際用例

Monad 和函子不僅僅是理論構造;它們也是。它們在現實世界的程式設計上有實際的應用。讓我們探討一些常見的用例。

使用 Maybe Monad 處理可選值

Maybe monad 用於處理可選值,避免 null 或未定義的值,並提供安全的鍊式操作方式。

class Maybe {
  constructor(value) {
    this.value = value;
  }

  static of(value) {
    return new Maybe(value);
  }

  isNothing() {
    return this.value === null || this.value === undefined;
  }

  map(fn) {
    return this.isNothing() ? this : Maybe.of(fn(this.value));
  }

  flatMap(fn) {
    return this.isNothing() ? this : fn(this.value);
  }
}

// Usage
const maybeValue = Maybe.of('hello')
  .map(str => str.toUpperCase())
  .flatMap(str => Maybe.of(`${str} WORLD`));
console.log(maybeValue); // Maybe { value: 'HELLO WORLD' }

在此範例中,Maybe monad 安全地處理可選值,僅當該值不為 null 或未定義時才允許轉換。

使用 Promise Monad 處理非同步操作

JavaScript 中的 Promise 是處理非同步操作的 monad,提供了一種連結操作和處理錯誤的方法。

const fetchData = url => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve(`Data from ${url}`);
    }, 1000);
  });
};

// Usage
fetchData('https://api.example.com')
  .then(data => {
    console.log(data); // 'Data from https://api.example.com'
    return fetchData('https://api.example.com/2');
  })
  .then(data => {
    console.log(data); // 'Data from https://api.example.com/2'
  })
  .catch(error => {
    console.error(error);
  });

Promise 讓您以乾淨且可組合的方式處理非同步操作,優雅地連結操作和處理錯誤。

Monad 和函子是函數式程式設計中強大的抽象,使您能夠以更結構化和可預測的方式處理資料轉換、副作用和組合。

雖然單子和函子的數學基礎可能很複雜,但它們的實際應用在現實世界的程式設計中非常有價值。無論您是使用 Maybe monad 處理可選值還是使用 Promises 管理非同步操作,這些函數式程式設計技術都可以幫助您建立更健壯、更可靠的應用程式。

版本聲明 本文轉載於:https://dev.to/francescoagati/introduction-to-functional-programming-in-javascript-monad-and-functors-7-1l6l?1如有侵犯,請聯絡[email protected]刪除
最新教學 更多>
  • 如何使用Java正則表達式來匹配不含特定字符的模式?
    如何使用Java正則表達式來匹配不含特定字符的模式?
    匹配模式不在Java中的某些字符中,正則表達式具有強大的模式匹配能力。一個特定的任務是僅在未指定字符之前匹配模式。 實現這一目標,可以使用負面的lookbehinds。負lookbehinds使用語法(?
    程式設計 發佈於2025-02-06
  • 在映射到MySQL枚舉列時,如何確保冬眠保留值?
    在映射到MySQL枚舉列時,如何確保冬眠保留值?
    在hibernate中保存枚舉值:故障排除錯誤的列type ,他們各自的映射至關重要。在Java中使用枚舉類型時,至關重要的是,建立冬眠的方式如何映射到基礎數據庫。 在您的情況下,您已將MySQL列定義為枚舉,並在Java中創建了相應的枚舉代碼。但是,您遇到以下錯誤:“ MyApp中的錯誤列類型...
    程式設計 發佈於2025-02-06
  • 如何以最簡單的方式在Mac上部署開發環境?完成INUTE!
    如何以最簡單的方式在Mac上部署開發環境?完成INUTE!
    在努力工作並省錢之後,我清空了錢包,並在上個月末購買了一個新的Mac,但是一旦得到它,我就開始頭痛。 作為開發人員,我知道“切割木頭之前銳化刀”的重要性,因此我準備在切換到Mac後安裝各種開發工具。由於我一直使用Windows,因此我準備使用Docker根據習慣部署和管理我的開發環境。 但是,在準...
    程式設計 發佈於2025-02-06
  • 如何為PostgreSQL中的每個唯一標識符有效地檢索最後一行?
    如何為PostgreSQL中的每個唯一標識符有效地檢索最後一行?
    [2最後一行與數據集中的每個不同標識符關聯。考慮以下數據: 1 2014-02-01 kjkj 1 2014-03-11 ajskj 3 2014-02-01 sfdg 3 2014-06-12 fdsa 在(ID)上選擇DISTINC 來自the_table 按ID訂單,date desc;...
    程式設計 發佈於2025-02-06
  • 如何使用Python的記錄模塊實現自定義處理?
    如何使用Python的記錄模塊實現自定義處理?
    使用Python的Loggging Module 確保正確處理和登錄對於疑慮和維護的穩定性至關重要Python應用程序。儘管手動捕獲和記錄異常是一種可行的方法,但它可能乏味且容易出錯。 解決此問題,Python允許您覆蓋默認的異常處理機制,並將其重定向為登錄模塊。這提供了一種方便而係統的方法來捕獲...
    程式設計 發佈於2025-02-06
  • HTML格式標籤
    HTML格式標籤
    HTML 格式化元素 **HTML Formatting is a process of formatting text for better look and feel. HTML provides us ability to format text without us...
    程式設計 發佈於2025-02-06
  • 如何使用反射調用數據庫/sql lows.scan()variadic函數?
    如何使用反射調用數據庫/sql lows.scan()variadic函數?
    您想動態填充一個從查詢獲得的值並利用lows.scan()提取數據的切片。在這種情況下,您需要確定列的數量並創建一個切片以存儲值。 一個公共陷阱:嘗試使用反射來調用掃描()函數可能會導致意外結果。這是因為rows.scan()期望指向值,而簡單地傳遞接口{}值將導致nil引用。 solution...
    程式設計 發佈於2025-02-06
  • 如何使用PHP將斑點(圖像)正確插入MySQL?
    如何使用PHP將斑點(圖像)正確插入MySQL?
    在嘗試將image存儲在mysql數據庫中時,您可能會遇到一個可能會遇到問題。本指南將提供成功存儲您的圖像數據的解決方案。 easudy values('$ this-> ; image_id','file_get_contents($ tmp_imag...
    程式設計 發佈於2025-02-06
  • 如何使用char_length()在mySQL中按字符串長度對數據進行排序?
    如何使用char_length()在mySQL中按字符串長度對數據進行排序?
    [2使用內置的char_length()function。 char_length()和length() 此查詢將從指定的表中檢索所有行,並基於上升順序對它們進行排序指定列的字符長度。帶有更長字符串的行將出現在結果的底部。
    程式設計 發佈於2025-02-06
  • 如何使用FormData()處理多個文件上傳?
    如何使用FormData()處理多個文件上傳?
    )處理多個文件輸入時,通常需要處理多個文件上傳時,通常是必要的。可以將fd.append("fileToUpload[]", files[x]);方法用於此目的,允許您在單個請求中發送多個文件。 初始嘗試 在JavaScript中,一種常見方法是:); 但是,此代碼僅處理第...
    程式設計 發佈於2025-02-06
  • 如何在Java列表中有效計算元素的發生?
    如何在Java列表中有效計算元素的發生?
    計數列表中的元素出現在列表 中,在java編程中,列舉列表中列舉元素出現的任務來自列表。為此,收集框架提供了全面的工具套件。 在這種情況下,Batocurrences變量將保持值3,代表動物列表中的“ BAT”出現的數量。 &&& [此方法是簡單的,可以得出準確的結果,使其成為計算列表中元素出現的...
    程式設計 發佈於2025-02-06
  • \“(1)vs.(;;):編譯器優化是否消除了性能差異?\”
    \“(1)vs.(;;):編譯器優化是否消除了性能差異?\”
    使用(1)而不是(;;)會導致無限循環的性能差異? 現代編譯器,(1)和(;;)之間沒有性能差異。 是如何實現這些循環的技術分析在編譯器中: perl: S-> 7 8 unstack v-> 4 -e語法ok 在GCC中,兩者都循環到相同的彙編代碼中,如下所示:。 globl t_時 ...
    程式設計 發佈於2025-02-06
  • C#中靜態變量的功率和局限性是什麼?
    C#中靜態變量的功率和局限性是什麼?
    [2 [2 靜態變量是C#的基本功能,在面向對象的編程中起著重要作用。 與實例變量不同,它們獨立於任何特定對象,維護在類的所有實例中共享的單個值。 [2 幾個關鍵好處使靜態變量有價值: 數據共享:靜態變量為在多個類實例之間共享數據提供了方便的機制。 這對於管理全局常數,應用程序設置或跟踪共享狀...
    程式設計 發佈於2025-02-06
  • 為什麼MySQL返回錯誤2014:“當其他未封閉的查詢處於活動狀態時無法執行查詢”?
    為什麼MySQL返回錯誤2014:“當其他未封閉的查詢處於活動狀態時無法執行查詢”?
    的原因2014:無法執行查詢,而其他未封閉的查詢是活動的在執行無封閉的查詢並試圖執行另一個查詢之前從中撤回所有行時首先,MySQL返回錯誤“無法執行查詢,而其他未封閉的查詢處於活動狀態。” 仿真準備的語句 有幾種解決此錯誤的方法: 使用buffered Queries: 關閉光標:使用colle...
    程式設計 發佈於2025-02-06
  • 如何從PHP中的源URL中檢索重定向URL?
    如何從PHP中的源URL中檢索重定向URL?
    從php /S/2e34796f/l/0l0sliberoquotidiano0bit0cnews0c12735670ci0esaggi0eper0ele0er0er0eriforme0ecostituzionaliiechiactuiaieiechiaccherano0eee0eee0ee...
    程式設計 發佈於2025-02-06

免責聲明: 提供的所有資源部分來自互聯網,如果有侵犯您的版權或其他權益,請說明詳細緣由並提供版權或權益證明然後發到郵箱:[email protected] 我們會在第一時間內為您處理。

Copyright© 2022 湘ICP备2022001581号-3