title: Type inference in MaybeMonad
body: <p>I'm trying out an example from this <a href="https://mikhail.io/2016/01/monads-explained-in-csharp/" rel="nofollow noreferrer">site</a> but running into following inference problem.</p>
  
  <p>The example is about maybe Monads and saves from continuous null checking and write code in a linear fashion.</p>
  
  <blockquote>
    <p>The type arguments for method <code>Maybe&lt;Customer&gt;.Bind&lt;TO&gt;(Func&lt;Customer,
    Maybe&lt;TO&gt;&gt;)</code> cannot be inferred from the usage. Try specifying the
    type arguments explicitly.</p>
  </blockquote>
  
  <p><strong>Maybe.cs</strong></p>
  
  <pre><code>using System;
  
  namespace Monads
  {
      public class Maybe&lt;T&gt; where T : class
      {
          private readonly T value;
  
          public Maybe(T someValue) 
          {
              if(someValue == null) 
                  throw new ArgumentNullException(nameof(someValue));
              this.value = someValue;
          }
  
          private Maybe(){}
  
          public Maybe&lt;TO&gt; Bind&lt;TO&gt;(Func&lt;T, Maybe&lt;TO&gt;&gt; func) where TO : class
          {
              return value != null ? func(value) : Maybe&lt;TO&gt;.None();
          }
  
          public static Maybe&lt;T&gt; None() =&gt; new Maybe&lt;T&gt;();
      }
  }
  </code></pre>
  
  <p><strong>IMonadicRepository</strong></p>
  
  <pre><code>namespace Monads
  {
      public interface IMonadicRepository
      {
         Maybe&lt;Customer&gt; GetCustomer(int id);
         Maybe&lt;Address&gt; GetAddress(int id);
      }
  }
  </code></pre>
  
  <p><strong>Repository.cs</strong></p>
  
  <pre><code>namespace Monads {
      public class Repository : IMonadicRepository
      {
          public Maybe&lt;Customer&gt; GetCustomer(int id) {
              return new Maybe&lt;Customer&gt;(new Customer(id));
          }
  
          public Maybe&lt;Address&gt; GetAddress(int id)
          {
              return new Maybe&lt;Address&gt;(new Address(id));
          }
      }
  }
  </code></pre>
  
  <p><strong>Customer.cs</strong></p>
  
  <pre><code>namespace Monads
  {
      public class Customer 
      {
          public Customer(int id) {
          }
  
          public Address Address {get; set;}
      }
  }
  </code></pre>
  
  <p><strong>Address.cs</strong></p>
  
  <pre><code>namespace Monads 
  {
      public class Address 
      {
          public Address(int id) {
          }
      }
  }
  </code></pre>
  
  <p><strong>Usage - Programs.cs</strong></p>
  
  <pre><code>namespace Monads
  {
      class Program
      {
          static void Main(string[] args)
          {
              IMonadicRepository repository = new Repository();
              repository.GetCustomer(1)
                  .Bind(customer =&gt; customer.Address); // error
          }
      }
  }
  </code></pre>
  
  <p><strong>Error</strong>: The type arguments for method <code>'Maybe.Bind(Func&gt;)'</code> cannot be inferred from the usage. Try specifying the type arguments explicitly.</p>