title: Multiple Dispatch Swift attempt: Conflicting arguments to generic parameter 'T' ('Cat' vs. 'Dog')
body: <p>I was watching a video on Julia about Multiple Dispatch and was curious if I could write something similar in Swift. I see that Swift relies on the compiler where Julia seems to determine a type at run time, but I also discovered something I don't understand about Swift.</p>
  <p>Why would the below function <code>encounters</code> work when the 2 parameters are of the same type of Pet but not when one is a Cat and the other is a Dog?</p>
  <p>For example the two functions below work</p>
  <pre><code>encounters(Arturo, Gabby) // both Cat
  encounters(Cc, Bb) // both Dog
  </code></pre>
  <p>but these give a compiler error</p>
  <blockquote>
  <p>Conflicting arguments to generic parameter 'T' ('Cat' vs. 'Dog')</p>
  </blockquote>
  <pre><code>encounters(Arturo, Bb) // Cat and Dog
  encounters(Bb, Arturo) // Dog and Cat
  </code></pre>
  <pre><code>protocol Pet: Equatable {
      var name: String { get }
  }
  struct Cat: Pet {
      let name: String
  }
  struct Dog: Pet {
      let name: String
  }
  
  let Arturo = Cat(name: &quot;Arturo&quot;)
  let Gabby = Cat(name: &quot;Gabby&quot;)
  let Bb = Dog(name: &quot;Bb&quot;)
  let Cc = Dog(name: &quot;Cc&quot;)
  
  func encounters&lt;T: Pet&gt;(_ a: T, _ b: T) {
      var verb: String
      switch (a, b) {
      case is (Cat, Dog):
          verb = meet(a as! Cat, b as! Dog)
      case is (Dog, Dog):
          verb = meet(a as! Dog, b as! Dog)
      case is (Cat, Cat):
          verb = meet(a as! Cat, b as! Cat)
      case is (Dog, Cat):
          verb = meet(a as! Dog, b as! Cat)
          
      default:
          fatalError()
      }
      
      print(&quot;\(a.name) meets \(b.name) and \(verb)&quot;)
  }
  
  func meet(_ a: Cat, _ b: Cat) -&gt; String {
      return &quot;Slinks&quot;
  }
  
  func meet(_ a: Cat, _ b: Dog) -&gt; String {
      return &quot;Hisses&quot;
  }
  
  func meet(_ a: Dog, _ b: Dog) -&gt; String {
      return &quot;Howles&quot;
  }
  
  func meet(_ a: Dog, _ b: Cat) -&gt; String {
      return &quot;Barks&quot;
  }
  </code></pre>