繁体   English   中英

C#中的Monadic理解语法

[英]Monadic comprehension syntax in C#

几天前我一直在#haskell IRC房间里闲逛,有人提到C#具有进行monadic理解的语法。 这是什么意思?

如果我理解正确的,一元的理解仅仅是一个排序的方式bind操作,哪一种听起来像一个do记号? 那是对的吗?

问题是我在C#中没有看到这个。 据我所知, IEnumerable<T>是一个monad,其中SelectMany是它的bind函数,因为它的签名是A -> IEnumerable<B> 只需一点想象力,我们就可以做到

from x in xs
from y in ys

这转化为( 我不是100%肯定在这里

xs.SelectMany(x => ys.Select(y => y), (x, y) => ...)

但即使这是真的,我们将LINQ视为monad理解语法,它仍然只适用于IEnumerable<T> 我们在C#中有其他monad,比如Task<T> ,但我们怎样才能在那些上使用LINQ?

这个问题中的许多假设可能是完全错误的,因为我仍然试图掌握一些monad神奇的东西。 如果我错了请纠正我:)

LINQ查询语法只是语法糖,并且对IEnumerable<>一无所知,这就是为什么你可以将它用于其他事情。

如果检查C#语言规范 ,它将描述如何在7.16.2节中转换LINQ的查询表达式

C#语言未指定查询表达式的执行语义。 相反,查询表达式被转换为符合查询表达式模式(第7.16.3节)的方法的调用。 具体来说,查询表达式被转换为名为Where,Select,SelectMany,Join,GroupJoin,OrderBy,OrderByDescending,ThenBy,ThenByDescending,GroupBy和Cast的方法的调用。这些方法应具有特定的签名和结果类型,如§中所述7.16.3。 这些方法可以是被查询对象的实例方法,也可以是对象外部的扩展方法,它们实现查询的实际执行。

您的具体示例描述为

带有第二个from子句后跟select子句的查询表达式

from x1 in e1
from x2 in e2
select v

被翻译成

( e1 ) . SelectMany( x1 => e2 , ( x1 , x2 ) => v )

因此,使用从实施例中的变量名,任何xs具有方法Treturned SelectMany(Func<Tx,Tys>, Func<Tx,Ty,Treturned>)可以在类似语句中使用

Treturned returned =
    from x in xs
    from y in ys
    select r;

这将完全编译时

Treturned returned = xs.SelectMany(x => ys, (x, y) => r);

是的,这是xs上存在这种方法的任何时候。 对于IEnumerable<>存在SelectMany的事实并不妨碍我们为其他类型配备具有相同名称的方法或扩展方法。

C#可以从它知道xs是什么的事实推断lambdas的类型,并且从中可以查找xsSelectMany参数的类型。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM