title: F# compiler throws OutOfMemoryException
body: <p>The project I use contains a lot of classes inherited from single base class. In unit tests I need to compare received results by types and data.</p>
  
  <p>When I use <em>match</em> comparison by types in the case when conditions list contains about enough many different conditions compiler throws OutOfMemoryException.</p>
  
  <p>For example, following F# code raises <em>System.OutOfMemoryException</em> (parameter error FS0193) during compilation (and compilation took about 30 seconds before exception was thrown)</p>
  
  <pre><code>type IBaseClass() = class end
  
  type IChildClass1 () = inherit IBaseClass () 
  
  type IChildClass2 () = inherit IBaseClass () 
  
  type IChildClass3 () = inherit IBaseClass () 
  
  type IChildClass4 () = inherit IBaseClass () 
  
  type IChildClass5 () = inherit IBaseClass () 
  
  type IChildClass6 () = inherit IBaseClass () 
  
  type IChildClass7 () = inherit IBaseClass () 
  
  type IChildClass8 () = inherit IBaseClass () 
  
  type IChildClass9 () = inherit IBaseClass () 
  
  type IChildClass10 () = inherit IBaseClass () 
  
  type IChildClass11 () = inherit IBaseClass () 
  
  type IChildClass12 () = inherit IBaseClass () 
  
  type IChildClass13 () = inherit IBaseClass () 
  
  type IChildClass14 () = inherit IBaseClass () 
  
  type IChildClass15 () = inherit IBaseClass () 
  
  type IChildClass16 () = inherit IBaseClass () 
  
  type IChildClass17 () = inherit IBaseClass () 
  
  type IChildClass18 () = inherit IBaseClass () 
  
  type IChildClass19 () = inherit IBaseClass () 
  
  type IChildClass20 () = inherit IBaseClass () 
  
  
  let AreEqual (original: IBaseClass) (compareWith: IBaseClass) : bool =
      match (original, compareWith) with
      | (:? IChildClass1 as a), (:? IChildClass1 as b) -&gt; a = b
      | (:? IChildClass2 as a), (:? IChildClass2 as b) -&gt; a = b
      | (:? IChildClass3 as a), (:? IChildClass3 as b) -&gt; a = b
      | (:? IChildClass4 as a), (:? IChildClass4 as b) -&gt; a = b
      | (:? IChildClass5 as a), (:? IChildClass5 as b) -&gt; a = b
      | (:? IChildClass6 as a), (:? IChildClass6 as b) -&gt; a = b
      | (:? IChildClass7 as a), (:? IChildClass7 as b) -&gt; a = b
      | (:? IChildClass8 as a), (:? IChildClass8 as b) -&gt; a = b
      | (:? IChildClass9 as a), (:? IChildClass9 as b) -&gt; a = b
      | (:? IChildClass10 as a), (:? IChildClass10 as b) -&gt; a = b
      | (:? IChildClass11 as a), (:? IChildClass11 as b) -&gt; a = b
      | (:? IChildClass12 as a), (:? IChildClass12 as b) -&gt; a = b
      | (:? IChildClass13 as a), (:? IChildClass13 as b) -&gt; a = b
      | (:? IChildClass14 as a), (:? IChildClass14 as b) -&gt; a = b
      | (:? IChildClass15 as a), (:? IChildClass15 as b) -&gt; a = b
      | (:? IChildClass16 as a), (:? IChildClass16 as b) -&gt; a = b
      | (:? IChildClass17 as a), (:? IChildClass17 as b) -&gt; a = b
      | (:? IChildClass18 as a), (:? IChildClass18 as b) -&gt; a = b
      | (:? IChildClass19 as a), (:? IChildClass19 as b) -&gt; a = b
      | (:? IChildClass20 as a), (:? IChildClass20 as b) -&gt; a = b
      | _ -&gt; false
  </code></pre>
  
  <p>For sure I can add IEquatable interface to my IBaseClass class that's will avoid usage of such <em>match</em> construction, or add <em>int Kind</em> member (or enum) to the 
  IBaseClass interface and make <em>match</em> not by types, but by some int value.</p>
  
  <p>Note, I've tried to compile the same project in MS VS 2010 and MSVS 11 Beta, and had the same compiler error</p>
  
  <p><strong>Question: Why the compiler's OutOfMemoryException happens in my case (is it known compiler bug or other limitation), how should I reorganize my <em>match</em> condition to avoid it?</strong></p>
  
  <p><strong>Update</strong> When I put classes into discriminated unions and use similar <em>match</em> comparison Fsc.exe compiles the project without exception</p>
  
  <pre><code>type AllClasses = 
      | ChildClass1 of IChildClass1 | ChildClass2 of IChildClass2 | ChildClass3 of IChildClass3 | ChildClass4 of IChildClass4 | ChildClass5 of IChildClass5 | ChildClass6 of IChildClass6
      | ChildClass7 of IChildClass7 | ChildClass8 of IChildClass8 | ChildClass9 of IChildClass9 | ChildClass10 of IChildClass10 | ChildClass11 of IChildClass11 | ChildClass12 of IChildClass12
      | ChildClass13 of IChildClass13 | ChildClass14 of IChildClass14 | ChildClass15 of IChildClass15 | ChildClass16 of IChildClass16 | ChildClass17 of IChildClass17 | ChildClass18 of IChildClass18 
      | ChildClass19 of IChildClass19 | ChildClass20 of IChildClass20
  
  let AreEqual2 (original: AllClasses) (compareWith: AllClasses) : bool =
      match (original, compareWith) with
      | ChildClass1(a), ChildClass1(b) -&gt; a = b
      | ChildClass2(a), ChildClass2(b) -&gt; a = b
      | ChildClass3(a), ChildClass3(b) -&gt; a = b
      | ChildClass4(a), ChildClass4(b) -&gt; a = b
      | ChildClass5(a), ChildClass5(b) -&gt; a = b
      | ChildClass6(a), ChildClass6(b) -&gt; a = b
      | ChildClass7(a), ChildClass7(b) -&gt; a = b
      | ChildClass8(a), ChildClass8(b) -&gt; a = b
      | ChildClass9(a), ChildClass9(b) -&gt; a = b
      | ChildClass10(a), ChildClass10(b) -&gt; a = b
      | ChildClass11(a), ChildClass11(b) -&gt; a = b
      | ChildClass12(a), ChildClass12(b) -&gt; a = b
      | ChildClass13(a), ChildClass13(b) -&gt; a = b
      | ChildClass14(a), ChildClass14(b) -&gt; a = b
      | ChildClass15(a), ChildClass15(b) -&gt; a = b
      | ChildClass16(a), ChildClass16(b) -&gt; a = b
      | ChildClass17(a), ChildClass17(b) -&gt; a = b
      | ChildClass18(a), ChildClass18(b) -&gt; a = b
      | ChildClass19(a), ChildClass19(b) -&gt; a = b
      | ChildClass20(a), ChildClass20(b) -&gt; a = b
      | _ -&gt; false
  </code></pre>
  
  <p>Thanks</p>