日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Linq怎么支持Monad

發布時間:2025/5/22 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Linq怎么支持Monad 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
Linq怎么支持Monad

? 在上一篇創建了我們的第一個Monad, Identity<T>. 我們確定了類型要變成Monad, 它必須有一個type constructor(Identity<T>), 和兩個方法,Bind與ToIdentity

//a function Bind, allows us to compose Identity returning functionspublic static Identity<B> Bind<A,B>(this Identity<A>a, Func<A,Identity<B>func>) { return func(a.Value); }public static Identity<T>ToIdentity<T>(tis T Value) { return new Identity<T>(value); }

我也提到了在C#里 Bind有個不同的名字,SelectMany,它是為IEnumerable<T>定義的擴展方法, 如你所知,IEnumerable<T>也是一個Monad,實際上它是C#里Monad的代表.

??????? 今天我們來看下如何為Identity<T>實現SelectMany, 并且去掉繁瑣的lambda表達式

Linq要求我們寫一個函數來結合Bind和To****的功能,SelectMany,SelectMany簽名必須如下:

Identity<C>SelectMany<A,B,C>(this Identity<A>a,Func<A,Identity<B>>func,Func<A,B,C>select)

它看起來像Bind函數,只是多了一個select參數,它以A,B為參數,返回C。 并且有一個不同的返回類型Identity<C>,替代Identity<B>. 如果你的amplified實現了SelectMany方法,在執行Linq的"from x in y"表達式時會轉換為SelectMany的調用.

讓我們將SelectMany實現為一個擴展方法:

public static Identity<C>SelectMany<A,B,C>(this Identity<A>a,Func<A,Identity<B>>func, Func<A,B,C>select) { return ??? }

現在要根據參數類型來寫出實現,首先我們知道要返回Identity<C>, 只有select Func可以返回C,我們可以調用ToIdentity將C轉換為Identity<C>

public static Identity<C>SelectMany<A,B,C>(this Identity<A>a,Func<A,Identity<B>>func, Func<A,B,C>select) { return select(???).ToIdentity(); }

傳什么給select呢, 第一個參數是A,我們可以調用a.Value得到A, 第二個參數B,我們可以通過Bind函數得到B

public static Identity<C>SelectMany<A,B,C>(this Identity<A>a,Func<A,Identity<B>>func, Func<A,B,C>select) { return (a.Value,a.Bind(func).Value).ToIdentity(); }

讓我們展開Bind函數,在這里Bind并沒有多大用

public static Identity<C>SelectMany<A,B,C>(this Identity<A>a,Func<A,Identity<B>>func, Func<A,B,C>select) { return select(a.Value,func(a.Value).Value).ToIdentity(); }

我們已經為Identity<T>實現了SelectMany. 現在我們可以用Linq語法替換我們上一篇的lambda表達式:

var result="Hello World!".ToIdentity().Bind(a=>7.ToIdentity().Bind(b=>(new DateTime(2010,1,11)).ToIdentity().Bind(c=>(a+", "+b.ToString()+", "+c.ToShortDateString()).ToIdentity())));var result=from a in "Hello World".ToIdentity()from b in 7.ToIdentity()from c in (new DateTime(2010,1,11)).ToIdentity()select a+", "+b.ToString()+", "+c.ToShortDateString();Console.WriteLine(result.Value);

是不是清晰很多?通過新視角看Linq和Monad, 我們可以把"from x in y"看做是Monad式的賦值,將將右側的amplified value 賦值給左側的unamplified type。

實際上你可以對任何WhatEver<T>使用Linq語法,而不僅僅是IEnumerable<T>。如果你想使用其他linq 語法如where,let,join等,你必須實現對應的方法, 他們都可以使用Bind創建

posted on 2016-06-27 23:30 哨兵 閱讀(...) 評論(...) 編輯 收藏

轉載于:https://www.cnblogs.com/phenixyu/p/5621915.html

總結

以上是生活随笔為你收集整理的Linq怎么支持Monad的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。