title: In C# adding SelectMany extends linq to a new monad type, how do I do the same thing in VB.net?
body: <p>An old <a href="http://blogs.msdn.com/wesdyer/archive/2008/01/11/the-marvels-of-monads.aspx" rel="nofollow noreferrer">Yet Another Language Geek blog post</a> explaining monads describes adding a SelectMany extension method to C# in order to extend the linq syntax to new types.</p>
  
  <p>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?</p>
  
  <p>Here is the C# code which works:</p>
  
  <pre><code>class Identity&lt;T&gt; {
      public readonly T Value;
      public Identity(T value) { this.Value = value; }
  }
  static class MonadExtension {
      public static Identity&lt;T&gt; ToIdentity&lt;T&gt;(this T value) {
          return new Identity&lt;T&gt;(value);
      }
      public static Identity&lt;V&gt; SelectMany&lt;T, U, V&gt;(this Identity&lt;T&gt; id, Func&lt;T, Identity&lt;U&gt;&gt; k, Func&lt;T, U, V&gt; 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;
      }
  }
  </code></pre>
  
  <p>Here is the VB.net code which doesn't work (note: written in vs2010, so may be missing some line continuations):</p>
  
  <pre><code>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
      &lt;Extension()&gt; _
      Public Function ToIdentity(Of T)(ByVal value As T) As Identity(Of T)
          Return New Identity(Of T)(value)
      End Function
      &lt;Extension()&gt; _
      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
  </code></pre>