title: Railway Oriented programming in C# - How do I write the switch function?
body: <p>I've been following <a href="http://fsharpforfunandprofit.com/posts/recipe-part2/" rel="noreferrer">this F# ROP article</a>, and decided to try and reproduce it in C#, mainly to see if I could. Apologies for the length of this question, but if you're familiar with ROP, it will be very easy to follow.</p>
  
  <p>He started off with an F# discriminated union...</p>
  
  <pre class="lang-fs prettyprint-override"><code>type Result&lt;'TSuccess, 'TFailure&gt; =
    | Success of 'TSuccess
    | Failure of 'TFailure
  </code></pre>
  
  <p>...which I translated into an abstract RopValue class, and two concrete implementations (note that I have changed the class names to ones that I understood better)...</p>
  
  <pre><code>public abstract class RopValue&lt;TSuccess, TFailure&gt; {
    public static RopValue&lt;TSuccess, TFailure&gt; Create&lt;TSuccess, TFailure&gt;(TSuccess input) {
      return new Success&lt;TSuccess, TFailure&gt;(input);
    }
  }
  
  public class Success&lt;TSuccess, TFailure&gt; : RopValue&lt;TSuccess, TFailure&gt; {
    public Success(TSuccess value) {
      Value = value;
    }
    public TSuccess Value { get; set; }
  }
  
  public class Failure&lt;TSuccess, TFailure&gt; : RopValue&lt;TSuccess, TFailure&gt; {
    public Failure(TFailure value) {
      Value = value;
    }
    public TFailure Value { get; set; }
  }
  </code></pre>
  
  <p>I added a static Create method to allow you to create a RopValue from a TSuccess object, which would be fed into the first of the validation functions.</p>
  
  <p>I then went about writing a binding function. The F# version was as follows...</p>
  
  <pre class="lang-fs prettyprint-override"><code>let bind switchFunction twoTrackInput =
    match twoTrackInput with
    | Success s -&gt; switchFunction s
    | Failure f -&gt; Failure f
  </code></pre>
  
  <p>...which was a doddle to read compared to the C# equivalent! I don't know if there is a simpler way to write this, but here is what I came up with...</p>
  
  <pre><code>public static RopValue&lt;TSuccess, TFailure&gt; Bind&lt;TSuccess, TFailure&gt;(this RopValue&lt;TSuccess, TFailure&gt; input, Func&lt;RopValue&lt;TSuccess, TFailure&gt;, RopValue&lt;TSuccess, TFailure&gt;&gt; switchFunction) {
    if (input is Success&lt;TSuccess, TFailure&gt;) {
      return switchFunction(input);
    }
    return input;
  }
  </code></pre>
  
  <p>Note that I wrote this as an extension function, as that allowed me to use it in a more functional way.</p>
  
  <p>Taking his use case of validating a person, I then wrote a Person class...</p>
  
  <pre><code>public class Person {
    public string Name { get; set; }
    public string Email { get; set; }
    public int Age { get; set; }
  }
  </code></pre>
  
  <p>...and wrote my first validation function...</p>
  
  <pre><code>public static RopValue&lt;Person, string&gt; CheckName(RopValue&lt;Person, string&gt; res) {
    if (res.IsSuccess()) {
      Person person = ((Success&lt;Person, string&gt;)res).Value;
      if (string.IsNullOrWhiteSpace(person.Name)) {
        return new Failure&lt;Person, string&gt;("No name");
      }
      return res;
    }
    return res;
  }
  </code></pre>
  
  <p>With a couple of similar validations for email and age, I could write an overall validation function as follows...</p>
  
  <pre><code>private static RopValue&lt;Person, string&gt; Validate(Person person) {
    return RopValue&lt;Person, string&gt;
      .Create&lt;Person, string&gt;(person)
      .Bind(CheckName)
      .Bind(CheckEmail)
      .Bind(CheckAge);
  }
  </code></pre>
  
  <p>This works fine, and enables me to do something like this...</p>
  
  <pre><code>Person jim = new Person {Name = "Jim", Email = "", Age = 16};
  RopValue&lt;Person, string&gt; jimChk = Validate(jim);
  Debug.WriteLine("Jim returned: " + (jimChk.IsSuccess() ? "Success" : "Failure"));
  </code></pre>
  
  <p>However, I have a few issues with the way I've done this. First off is that the validation functions require you to pass in a RopValue, check it for Success or Failure, if Success, pull out the Person and then validate it. If Failure, just return it.</p>
  
  <p>By contrast, his validation functions took (the equivalent of) a Person, and returned (a Result, which is the equivalent of) a RopValue...</p>
  
  <pre class="lang-fs prettyprint-override"><code>let validateNameNotBlank person =
    if person.Name = "" then Failure "Name must not be blank"
    else Success person
  </code></pre>
  
  <p>This is much simpler, but I was unable to work out how to do this in C#.</p>
  
  <p>Another issue is that we start the validation chain with a Success&lt;>, so the first validation function will always return something from the "if" block, either a Failure&lt;> if the validation failed, or a Success&lt;> if we got past the checks. If a function returns Failure&lt;>, then the next function in the validation chain never gets called, so it turns out that we know that these methods can never be passed a Failure&lt;>. Therefore, the final line of each of these functions can never be reached (other than in the weird case that you manually created a Failure&lt;> and passed it in at the start, but that would be pointless).</p>
  
  <p>He then created a switch operator (>=>) to connect validation functions. I tried doing this, but couldn't get it to work. In order to chain successive calls to the function, it looked like I'd have to have an extension method on a Func&lt;>, which I don't think you can do. I got as far as this...</p>
  
  <pre><code>public static RopValue&lt;TSuccess, TFailure&gt; Switch&lt;TSuccess, TFailure&gt;(this Func&lt;TSuccess, RopValue&lt;TSuccess, TFailure&gt;&gt; switch1, Func&lt;TSuccess, RopValue&lt;TSuccess, TFailure&gt;&gt; switch2, TSuccess input) {
    RopValue&lt;TSuccess, TFailure&gt; res1 = switch1(input);
    if (res1.IsSuccess()) {
      return switch2(((Success&lt;TSuccess, TFailure&gt;)res1).Value);
    }
    return new Failure&lt;TSuccess, TFailure&gt;(((Failure&lt;TSuccess, TFailure&gt;)res1).Value);
  }
  </code></pre>
  
  <p>...but couldn't work out how to use it.</p>
  
  <p>So, can anyone explain how I would write the Bind function so that it can take a Person and return a RopValue (like his does)? Also how do I write a switch function which will allow me to connect simple validation functions?</p>
  
  <p>Any other comments on my code are welcome. I'm not sure it's anywhere near as neat and simple as it could be.</p>