title: Playing with F# types and getting lost
body: <p>I have been doing a little reading on F# and decided to give it a try. I started with a somewhat involved example and I came up with and got lost immediately. I wonder if someone can share some thoughts on it.</p>
  
  <p>I wanted to write a method called <code>ComparisonStrategy&lt;'T&gt;</code> that returns an instance of <code>IEqualityComparer&lt;'T&gt;</code>. It that takes in a variable length of <code>ComparisonWhichAndHow&lt;'T&gt;</code> instances. The type <code>ComparisonWhichAndHow&lt;'T&gt;</code> can either be:</p>
  
  <ol>
  <li>One function of type <code>('T -&gt; *)</code>, which is a method that selects a single field to compare</li>
  <li>a 2-tuple of <code>('T -&gt; 'U, IEqualityComparer&lt;'U&gt;)</code> if you don't want the default <code>Equals</code> or <code>GetHashCode</code> to be used on <code>'U</code>.</li>
  </ol>
  
  <p>I have tried to draw this down on visual studio for a while now, but I can't even get the function declaration part right. I am somewhat positive I would be able to implement the method body if I can just get past this, but seems like I can't.</p>
  
  <p>Edited:</p>
  
  <p>This is the code I have tried so far.</p>
  
  <p>I am trying to achieve the 2 following things.</p>
  
  <ol>
  <li>Come up with a generic way of generating a equal method for each object.</li>
  <li>Sometimes some business operations might require comparing some fields of 2 objects, and some fields of their children. Not a full comparison. I am trying to make writing those code more concise and simple</li>
  </ol>
  
  <p>This is what I have so far:</p>
  
  <pre><code>module Failed =
      open System.Collections.Generic
      open System
  
      type ComparsionOption&lt;'T, 'U&gt; =
          | Compare of ('T -&gt; 'U)
          | CompareWith of ('T -&gt; 'U) * IEqualityComparer&lt;'U&gt;
  
      // TO USE: [&lt;ParamArray&gt;] 
      // TODO: this method returns a dummy for now
      let CompareStrategy (opts : ComparsionOption&lt;'T, _&gt; array) =
          EqualityComparer&lt;'T&gt;.Default
  
      // How it's used
  
      type Person(name : string, id : Guid) = 
          member this.Name = name
          member this.ID = id
  
      let fullCompare : EqualityComparer&lt;Person&gt; =
          CompareStrategy [|Compare(fun (p : Person) -&gt; p.Name);
                              CompareWith((fun (p : Person) -&gt; p.ID), EqualityComparer&lt;Guid&gt;.Default)|] // error here
  </code></pre>