Monad詳解

来源:http://www.cnblogs.com/fishbay/archive/2017/07/19/7204265.html
-Advertisement-
Play Games

最近幾年,函數式編程變得越來越流程,其代碼簡潔、副作用小、維護成本低等特點,使得許多其它的語言也開始支持函數式編程,比如`Java` 和 `C#`等。本文主要介紹一下函數式編程中的一個重要概念:`Monad`。 ...


最近幾年,函數式編程變得越來越流程,其代碼簡潔、副作用小、維護成本低等特點,使得許多其它的語言也開始支持函數式編程,比如JavaC#等。本文主要介紹一下函數式編程中的一個重要概念:Monad
  
  從定義上看,Monad就是兩個介面:一個是return,另一個是一個bind;只要實現這兩個操作的類型,都是monad。但是在理解Monad之前,先要搞清楚兩個概念:FunctorsApplicatives:
  

1. Functors

  • 定義:把一個函數作用在數值類型(對值類型的封裝,包含相關屬性和方法)上,用 fmap 或者 <$> 表示這種運算。

  • 常規運算:把一個函數作用在一個普通數值上

圖1

  • Functors運算: 如果把普通數值用上下文包括,生成一個數值類型,那麼函數將無法處理該數值類型

圖2

函數無法處理數值類型,於是就出現了Functors,它可以處理數值類型,例如:

> fmap (+3) (Just 2)
Just 5

> (+3) <$> (Just 2)
Just 5

圖3

具體操作步驟如下圖解:

圖4

如果數值類型為Nothing,那麼Functors作用後的結果也是Nothing:

圖5

2. Applicatives

  • 定義: 把一個封裝後的函數作用於數值類型(對值類型的封裝,包含相關屬性和方法),用liftA<*>定義這種運算。

  • 運演算法則:可以把Applicatives看成是Functors中的函數也被封裝了一層,然後再應用於數值類型

> Just (+3) <*> Just 2
Just 5

> liftA (Just (+3)) (Just 2)
Just 15

圖6

如果數值類型為Nothing,那麼Functors作用後的結果也是Nothing:

3. Monad

  • 定義: 把一個返回數值類型的函數作用於數值類型,用liftM>>=來定義這種運算。

  • 運演算法則:可以把Monad看成是Applicatives中的函數返回值也是數值類型

圖7

定義half是判斷是否是偶數的函數, 作用於數值類型20,過程如下:

> Just 20 >>= half >>= half >>= half
Nothing

圖8

如果數值類型為Nothing,那麼Functors作用後的結果也是Nothing:

圖9

由於Nothing作用於FunctorsApplicativesMonad時,都返回Nothing,所以它們都是Maybe類型。Maybe類型的定義如下:
data Maybe a = Nothing | Just a

圖9


參考資料

http://adit.io/posts/2013-04-17-functors,_applicatives,_and_monads_in_pictures.html

http://www.ruanyifeng.com/blog/2015/07/monad.html?utm_source=tuicool


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 註意:本教程使用的開發環境是:(專業版) 1 創建javaSE項目 1.1 file -> new -> project 註意:如果是第一次使用,就需要配置 project SDK , 就是制定一個JDK,將自己安裝好的JDK加進來就行啦 是否按照模板來創建(一般不選擇這一項) 設置項目名稱和項目存 ...
  • 前言:工作中看到項目組裡的大牛寫代碼大量的用到了StringUtils工具類來做字元串的操作,便學習整理了一下,方便查閱。 isEmpty(String str) 是否為空,空格字元為false isNotEmpty(String str) 是否為非空,空格字元為true isBlank(Strin ...
  • 給一個長為N的數列,有M次操作,每次操作是以下兩種之一: (1)將某連續一段同時改成一個數 (2)求數列中某連續一段的和 ...
  • 給一個長為N的數列,有M次操作,每次操作是以下兩種之一: (1)修改數列中的一個數 (2)求數列中某連續一段的和 ...
  • 一、JAVA高級併發 1.5JDK之後引入高級併發特性,大多數的特性在java.util.concurrent 包中,是專門用於多線程發編程的,充分利用了現代多處理器和多核心系統的功能以編寫大規模併發應用程式。主要包含原子量、併發集合、同步器、可重入鎖,並對線程池的構造提供了強力的支持。 二、線性池 ...
  • 非同步和多線程並不是一個同等關係,非同步是最終目的,多線程只是我們實現非同步的一種手段。非同步是當一個調用請求發送給被調用者,而調用者不用等待其結果的返回而可以做其它的事情。實現非同步可以採用多線程技術或則交給另外的進程來處理。 ...
  • 實現隨機驗證碼 ...
  • SSO英文全稱Single Sign On,單點登錄。SSO是在多個應用系統中,用戶只需要登錄一次就可以訪問所有相互信任的應用系統。它包括可以將這次主要的登錄映射到其他應用中用於同一個用戶的登錄的機制。它是目前比較流行的企業業務整合的解決方案之一。 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...