An old Yet Another Language Geek blog post explaining monads describes adding a SelectMany extension method to C# in order to extend the linq syntax to new types.
I've tried it in C# and it works. I did a straight conversion to VB.net and it doesn't work. Does anyone know if VB.net supports this feature or how to use it?
Here is the C# code which works:
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;
}
}
Here is the VB.net code which doesn't work (note: written in vs2010, so may be missing some line continuations):
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