Dar*_*rio 25
从功能上讲,LINQ只不过是表达monad的语法简化.Linq to Objects(List-comprehensions - 即使这已经非常有用),你一直在谈论它,这只是一个可能的应用程序(类似于Haskell中的List-Monad).
如果你写
from x in expr1
from y in expr2
select x + y
Run Code Online (Sandbox Code Playgroud)
它只不过是
do
x <- expr1
y <- expr2
return $ x + y
Run Code Online (Sandbox Code Playgroud)
在哈斯克尔.
完成的具体事情取决于用户定义的Linq-providers(Extension-Methods),它Linq.Enumerable只是一个涉及IEnumerables的实现.
通过提供一个,您可以为您的类型创建全新的LINQ语义.
示例:给定Option可能失败的计算类型(可空值),可以定义用于查询它们的Linq提供程序.
public static class MaybeExtensions
{
public static Option<T> ToMaybe<T>(this T value)
{
return Option<T>.Some(value);
}
public static Option<U> SelectMany<T, U>(
this Option<T> m,
Func<T, Option<U>> k)
{
return !m.IsNone ? Option<U>.None : k(m.Value);
}
public static Option<V> SelectMany<T, U, V>(
this Option<T> m,
Func<T, Option<U>> k,
Func<T, U, V> s)
{
return m.SelectMany(x => k(x).SelectMany(y => s(x, y).ToMaybe()));
}
}
Run Code Online (Sandbox Code Playgroud)
这将允许我们编写这样的代码:
var sum = from x in ReadNumber("x")
from y in ReadNumber("y")
select x + y;
Run Code Online (Sandbox Code Playgroud)
如果所有计算成功,计算将仅返回一个值,否则在第一个失败的计算失败时将失败.
结合表达树,Linq可以非常强大,并允许您表达 -
一些链接:
结合定点组合器,Linq提供了一个完整的功能迷你语言(Linq光线跟踪器).
请注意,Scala和F#在for-comprehensions和计算表达式中都有类似的概念,它们都是monadic抽象:
斯卡拉:
for (x <- expr1
y <- expr2) yield x + y
Run Code Online (Sandbox Code Playgroud)
F#:
monad {
let! x = expr1
let! y = expr2
return x + y
}
Run Code Online (Sandbox Code Playgroud)