一篇解释 monads的旧的Yet Another Language Geek 博客文章描述了向 C# 添加 SelectMany 扩展方法,以便将 linq 语法扩展到新类型。
我已经在 C# 中尝试过它并且它有效。我直接转换为 VB.net,但它不起作用。有谁知道 VB.net 是否支持此功能或如何使用它?
这是有效的 C# 代码:
class Identity<T> {
public readonly T Value;
public Identity(T value) { this.Value = value; }
}
static class MonadExtension {
public static Identity<T> ToIdentity<T>(this T value) {
return new Identity<T>(value);
}
public static Identity<V> SelectMany<T, U, V>(this Identity<T> id, Func<T, Identity<U>> k, Func<T, U, V> s) {
return s(id.Value, k(id.Value).Value).ToIdentity();
}
}
class Program {
static void Main(string[] args) {
var r = from x in 5.ToIdentity()
from y in 6.ToIdentity()
select x + y;
}
}
这是不起作用的VB.net代码(注意:用vs2010编写,因此可能缺少一些续行):
Imports System.Runtime.CompilerServices
Public Class Identity(Of T)
Public ReadOnly value As T
Public Sub New(ByVal value As T)
Me.value = value
End Sub
End Class
Module MonadExtensions
<Extension()> _
Public Function ToIdentity(Of T)(ByVal value As T) As Identity(Of T)
Return New Identity(Of T)(value)
End Function
<Extension()> _
Public Function SelectMany(Of T, U, V)(ByVal id As Identity(Of T), ByVal k As Func(Of T, Identity(Of U)), ByVal s As Func(Of T, U, V)) As Identity(Of V)
Return s(id.value, k(id.value).value).ToIdentity()
End Function
End Module
Public Module MonadTest
Public Sub Main()
''Error: Expression of type 'Identity(Of Integer)' is not queryable.
Dim r = From x In 5.ToIdentity() _
From y In 6.ToIdentity() _
Select x + y
End Sub
End Module