<div dir="ltr"><div class="gmail_default" style="font-family:georgia,serif">Hi Jordan,</div><div class="gmail_default" style="font-family:georgia,serif"><br></div><div class="gmail_default" style="font-family:georgia,serif">Both you and I were wrong. </div><div class="gmail_default" style="font-family:georgia,serif"><br></div><div class="gmail_default" style="font-family:georgia,serif">My wrongness: Your so called principle should be applied here.  </div><div class="gmail_default" style="font-family:georgia,serif"><br></div><div class="gmail_default" style="font-family:georgia,serif">Your wrongness: If you really want a different hash value, the parent equality function has to be conservative and say that the different types are different. </div><div class="gmail_default" style="font-family:georgia,serif"><br></div><div class="gmail_default" style="font-family:georgia,serif">Here is the conclusion.</div><div class="gmail_default" style="font-family:georgia,serif"><br></div><div class="gmail_default" style="font-family:georgia,serif"><div class="gmail_default" style="font-size:13px">The key is how to write the `==` function. It should compare the` dynamicType`(or `type(of:)` in Swift 3.0) if the class is not a final class.</div><div class="gmail_default" style="font-size:13px"><br></div><div class="gmail_default" style="font-family:arial,sans-serif;font-size:13px"><span class="gmail-im"><p style="font-family:menlo;margin:0px;font-size:11px;line-height:normal"><span style="color:rgb(187,44,162)">func</span> ==(lhs: <span style="color:rgb(79,129,135)">Fruit</span>, rhs: <span style="color:rgb(79,129,135)">Fruit</span>) -&gt; <span style="color:rgb(112,61,170)">Bool</span> {</p><p style="font-family:menlo;margin:0px;font-size:11px;line-height:normal;min-height:13px">    </p><p style="font-family:menlo;margin:0px;font-size:11px;line-height:normal">    <span style="color:rgb(61,29,129)">print</span>(lhs.<span style="color:rgb(79,129,135)">hashValue</span>)</p><p style="font-family:menlo;margin:0px;font-size:11px;line-height:normal">    <span style="color:rgb(61,29,129)">print</span>(rhs.<span style="color:rgb(79,129,135)">hashValue</span>)</p><p style="font-family:menlo;margin:0px;font-size:11px;line-height:normal;min-height:13px">    </p></span><p style="font-family:menlo;margin:0px;font-size:11px;line-height:normal">    <span style="color:rgb(187,44,162)">return</span> type(of:lhs) == type(of:rhs) <span style="color:rgb(61,29,129)">&amp;&amp;</span> lhs.<span style="color:rgb(79,129,135)">name</span> <span style="color:rgb(61,29,129)">==</span> rhs.<span style="color:rgb(79,129,135)">name</span></p><span class="gmail-im"><p style="font-family:menlo;margin:0px;font-size:11px;line-height:normal">}</p><p style="font-family:menlo;margin:0px;font-size:11px;line-height:normal;min-height:13px"><br></p><p style="font-family:menlo;margin:0px;font-size:11px;line-height:normal"><span style="color:rgb(187,44,162)">func</span> ==(lhs: <span style="color:rgb(79,129,135)">Apple</span>, rhs: <span style="color:rgb(79,129,135)">Apple</span>) -&gt; <span style="color:rgb(112,61,170)">Bool</span> {</p></span><p style="font-family:menlo;margin:0px;font-size:11px;line-height:normal">    <span style="color:rgb(187,44,162)">return</span> type(of:lhs) == type(of:rhs) <span style="color:rgb(61,29,129)">&amp;&amp;</span> lhs.<span style="color:rgb(79,129,135)">name</span> <span style="color:rgb(61,29,129)">==</span> rhs.<span style="color:rgb(79,129,135)">name</span> <span style="color:rgb(61,29,129)">&amp;&amp;</span> lhs.<span style="color:rgb(79,129,135)">shape</span> == rhs.<span style="color:rgb(79,129,135)">shape</span></p><span class="gmail-im"><p style="font-family:menlo;margin:0px;font-size:11px;line-height:normal">}</p><p style="font-family:menlo;margin:0px;font-size:11px;line-height:normal;min-height:13px"><br></p><p style="font-family:menlo;margin:0px;font-size:11px;line-height:normal"><span style="color:rgb(187,44,162)">func</span> ==(lhs: <span style="color:rgb(79,129,135)">Banana</span>, rhs: <span style="color:rgb(79,129,135)">Banana</span>) -&gt; <span style="color:rgb(112,61,170)">Bool</span> {</p></span><p style="font-family:menlo;margin:0px;font-size:11px;line-height:normal">    <span style="color:rgb(187,44,162)">return</span> type(of:lhs) == type(of:rhs) <span style="color:rgb(61,29,129)">&amp;&amp;</span> lhs.<span style="color:rgb(79,129,135)">name</span> <span style="color:rgb(61,29,129)">==</span> rhs.<span style="color:rgb(79,129,135)">name</span> <span style="color:rgb(61,29,129)">&amp;&amp;</span> lhs.<span style="color:rgb(79,129,135)">shape</span> == rhs.<span style="color:rgb(79,129,135)">shape</span></p><span class="gmail-im"><p style="font-family:menlo;margin:0px;font-size:11px;line-height:normal">}</p><p style="font-family:menlo;margin:0px;font-size:11px;line-height:normal;min-height:13px"><br></p><p style="font-family:menlo;margin:0px;font-size:11px;line-height:normal;min-height:13px"><br></p><p style="font-family:menlo;margin:0px;font-size:11px;line-height:normal"><span style="color:rgb(187,44,162)">class</span> Fruit:<span style="color:rgb(112,61,170)">Hashable</span> {</p><p style="font-family:menlo;margin:0px;font-size:11px;line-height:normal">    <span style="color:rgb(187,44,162)">let</span> name:<span style="color:rgb(112,61,170)">String</span></p><p style="font-family:menlo;margin:0px;font-size:11px;line-height:normal;min-height:13px">    </p><p style="font-family:menlo;margin:0px;font-size:11px;line-height:normal">    <span style="color:rgb(187,44,162)">var</span> hashValue: <span style="color:rgb(112,61,170)">Int</span> {</p><p style="font-family:menlo;margin:0px;font-size:11px;line-height:normal">        <span style="color:rgb(187,44,162)">return</span> <span style="color:rgb(39,42,216)">0</span></p><p style="font-family:menlo;margin:0px;font-size:11px;line-height:normal">    }</p><p style="font-family:menlo;margin:0px;font-size:11px;line-height:normal;min-height:13px">    </p><p style="font-family:menlo;margin:0px;font-size:11px;line-height:normal">    <span style="color:rgb(187,44,162)">init</span>(<span style="color:rgb(187,44,162)">_</span> name:<span style="color:rgb(112,61,170)">String</span> = <span style="color:rgb(209,47,27)">&quot;common fruit&quot;</span>) {</p><p style="font-family:menlo;margin:0px;font-size:11px;line-height:normal">        <span style="color:rgb(187,44,162)">self</span>.<span style="color:rgb(79,129,135)">name</span> = name</p><p style="font-family:menlo;margin:0px;font-size:11px;line-height:normal">    }</p><p style="font-family:menlo;margin:0px;font-size:11px;line-height:normal">}</p><p style="font-family:menlo;margin:0px;font-size:11px;line-height:normal;min-height:13px"><br></p><p style="font-family:menlo;margin:0px;font-size:11px;line-height:normal"><span style="color:rgb(187,44,162)">enum</span> FruitShape:<span style="color:rgb(112,61,170)">Int</span> {</p><p style="font-family:menlo;margin:0px;font-size:11px;line-height:normal">    <span style="color:rgb(187,44,162)">case</span> small = <span style="color:rgb(39,42,216)">1000</span></p><p style="font-family:menlo;margin:0px;font-size:11px;line-height:normal">    <span style="color:rgb(187,44,162)">case</span> medium = <span style="color:rgb(39,42,216)">2000</span></p><p style="font-family:menlo;margin:0px;font-size:11px;line-height:normal">    <span style="color:rgb(187,44,162)">case</span> big = <span style="color:rgb(39,42,216)">3000</span></p><p style="font-family:menlo;margin:0px;font-size:11px;line-height:normal">}</p><p style="font-family:menlo;margin:0px;font-size:11px;line-height:normal;min-height:13px"><br></p><p style="font-family:menlo;margin:0px;font-size:11px;line-height:normal"><span style="color:rgb(187,44,162)">class</span> Apple:<span style="color:rgb(79,129,135)">Fruit</span> {</p><p style="font-family:menlo;margin:0px;font-size:11px;line-height:normal">    <span style="color:rgb(187,44,162)">let</span> shape:<span style="color:rgb(79,129,135)">FruitShape</span></p><p style="font-family:menlo;margin:0px;font-size:11px;line-height:normal;min-height:13px">    </p></span><p style="font-family:menlo;margin:0px;font-size:11px;line-height:normal">    <span style="color:rgb(187,44,162)">override</span> <span style="color:rgb(187,44,162)">var</span> hashValue: <span style="color:rgb(112,61,170)">Int</span> {</p><p style="font-family:menlo;margin:0px;font-size:11px;line-height:normal">        <span style="color:rgb(187,44,162)">return</span> <span style="color:rgb(39,42,216)">5</span></p><p style="font-family:menlo;margin:0px;font-size:11px;line-height:normal">    }</p><p style="font-family:menlo;margin:0px;font-size:11px;line-height:normal;min-height:13px">    </p><p style="font-family:menlo;margin:0px;font-size:11px;line-height:normal">    <span style="color:rgb(187,44,162)">required</span> <span style="color:rgb(187,44,162)">init</span>(<span style="color:rgb(187,44,162)">_</span> name:<span style="color:rgb(112,61,170)">String</span> = <span style="color:rgb(209,47,27)">&quot;common fruit&quot;</span>, shape:<span style="color:rgb(79,129,135)">FruitShape</span> = .<span style="color:rgb(49,89,93)">medium</span>) {</p><p style="font-family:menlo;margin:0px;font-size:11px;line-height:normal">        <span style="color:rgb(187,44,162)">self</span>.<span style="color:rgb(79,129,135)">shape</span> = shape</p><p style="font-family:menlo;margin:0px;font-size:11px;line-height:normal">        <span style="color:rgb(187,44,162)">super</span>.<span style="color:rgb(187,44,162)">init</span>(name)</p><span class="gmail-im"><p style="font-family:menlo;margin:0px;font-size:11px;line-height:normal">    }</p><p style="font-family:menlo;margin:0px;font-size:11px;line-height:normal">}</p><p style="font-family:menlo;margin:0px;font-size:11px;line-height:normal;min-height:13px"><br></p><p style="font-family:menlo;margin:0px;font-size:11px;line-height:normal"><span style="color:rgb(187,44,162)">class</span> Banana:<span style="color:rgb(79,129,135)">Fruit</span> {</p><p style="font-family:menlo;margin:0px;font-size:11px;line-height:normal">    <span style="color:rgb(187,44,162)">let</span> shape:<span style="color:rgb(79,129,135)">FruitShape</span></p><p style="font-family:menlo;margin:0px;font-size:11px;line-height:normal;min-height:13px">    </p></span><p style="font-family:menlo;margin:0px;font-size:11px;line-height:normal">    <span style="color:rgb(187,44,162)">override</span> <span style="color:rgb(187,44,162)">var</span> hashValue: <span style="color:rgb(112,61,170)">Int</span> {</p><p style="font-family:menlo;margin:0px;font-size:11px;line-height:normal">        <span style="color:rgb(187,44,162)">return</span> <span style="color:rgb(39,42,216)">10</span></p><p style="font-family:menlo;margin:0px;font-size:11px;line-height:normal">    }</p><p style="font-family:menlo;margin:0px;font-size:11px;line-height:normal;min-height:13px">    </p><p style="font-family:menlo;margin:0px;font-size:11px;line-height:normal">    <span style="color:rgb(187,44,162)">required</span> <span style="color:rgb(187,44,162)">init</span>(<span style="color:rgb(187,44,162)">_</span> name:<span style="color:rgb(112,61,170)">String</span> = <span style="color:rgb(209,47,27)">&quot;common fruit&quot;</span>, shape:<span style="color:rgb(79,129,135)">FruitShape</span> = .<span style="color:rgb(49,89,93)">medium</span>) {</p><p style="font-family:menlo;margin:0px;font-size:11px;line-height:normal">        <span style="color:rgb(187,44,162)">self</span>.<span style="color:rgb(79,129,135)">shape</span> = shape</p><p style="font-family:menlo;margin:0px;font-size:11px;line-height:normal">        <span style="color:rgb(187,44,162)">super</span>.<span style="color:rgb(187,44,162)">init</span>(name)</p><span class="gmail-im"><p style="font-family:menlo;margin:0px;font-size:11px;line-height:normal">    }</p><p style="font-family:menlo;margin:0px;font-size:11px;line-height:normal">}</p><p style="font-family:menlo;margin:0px;font-size:11px;line-height:normal;min-height:13px"><br></p><p style="font-family:menlo;margin:0px;font-size:11px;line-height:normal"><span style="color:rgb(187,44,162)">let</span> apple = <span style="color:rgb(79,129,135)">Apple</span>()</p><p style="font-family:menlo;margin:0px;font-size:11px;line-height:normal"><span style="color:rgb(187,44,162)">let</span> banana = <span style="color:rgb(79,129,135)">Banana</span>()</p><p style="font-family:menlo;margin:0px;font-size:11px;line-height:normal;min-height:13px"><br></p><p style="font-family:menlo;margin:0px;font-size:11px;line-height:normal;color:rgb(79,129,135)"><span style="color:rgb(61,29,129)">print</span><span style="color:rgb(0,0,0)">(</span>apple<span style="color:rgb(0,0,0)"> </span><span style="color:rgb(49,89,93)">==</span><span style="color:rgb(0,0,0)"> </span>banana<span style="color:rgb(0,0,0)">)</span></p><p style="font-family:menlo;margin:0px;font-size:11px;line-height:normal;color:rgb(0,132,0)">/*</p><p style="font-family:menlo;margin:0px;font-size:11px;line-height:normal;color:rgb(0,132,0)"> 5</p><p style="font-family:menlo;margin:0px;font-size:11px;line-height:normal;color:rgb(0,132,0)"> 10</p></span><p style="font-family:menlo;margin:0px;font-size:11px;line-height:normal;color:rgb(0,132,0)"> false</p><p style="font-family:menlo;margin:0px;font-size:11px;line-height:normal;color:rgb(0,132,0)">*/</p><p style="font-family:menlo;margin:0px;font-size:11px;line-height:normal;color:rgb(0,132,0)"><br></p><p style="margin:0px;line-height:normal"><font face="georgia, serif" color="#000000">I got the idea from book &quot;Core Java&quot;, mine is version 8, the latest is the version 10. I learnt how to writing Object oriented code from it. I am glad it is still useful.</font></p><p style="margin:0px;line-height:normal"><font face="georgia, serif" color="#000000"><br></font></p><p style="margin:0px;line-height:normal"><font face="georgia, serif" color="#000000">Zhaoxin</font></p></div></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Sat, Sep 3, 2016 at 12:23 AM, Jordan Rose <span dir="ltr">&lt;<a href="mailto:jordan_rose@apple.com" target="_blank">jordan_rose@apple.com</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word"><div>This is incorrect. If I have a Set&lt;Fruit&gt;, I should expect that the set may contain Apples and Bananas. If you really want a different hash value, the parent equality function has to be conservative and say that the different types are different. But that’s <i>your</i> choice, because <i>you</i> wrote the implementation of Equatable for the base class. (And if you <i>didn’t,</i> then you should be concerned, because any functions that came with the base class will assume the Apple and the Banana are interchangeable.)</div><div><br></div><div>Remember, hashValue can return 0 for all instances and still be correct. The implications only work one way.</div><div><br></div><div>if a == b, then a.hashValue == b.hashValue</div><div>if a != b, then we know nothing about the hash values</div><div>if a.hashValue == b.hashValue, then we know nothing about a == b</div><div>if a.hashValue != b.hashValue, a != b</div><div><br></div><div>I’ll finish by repeating what I said earlier: if you plan to have a base class be Equatable, you need to design your == in such a way that it makes sense for subclasses. If you can’t do that, you either can’t be Equatable or can’t allow subclasses, or common uses of the standard library will break. How you <i>want</i> it work doesn’t matter if you don’t control ==.</div><span class="HOEnZb"><font color="#888888"><div><br></div><div>Jordan</div></font></span><div><div class="h5"><div><br></div><br><div><blockquote type="cite"><div>On Sep 1, 2016, at 22:50, Zhao Xin &lt;<a href="mailto:owenzx@gmail.com" target="_blank">owenzx@gmail.com</a>&gt; wrote:</div><br><div><div dir="ltr"><div class="gmail_default" style="font-family:georgia,serif">No. I don&#39;t think what you so called principle should be applied here. For example, I have a `class Fruit`, then I have a `class Apple:Fruit`. If they are using different `hashValue` generating method, you suggest me to use composition instead of inheritance?</div><div class="gmail_default" style="font-family:georgia,serif"><br></div><div class="gmail_default" style="font-family:georgia,serif">Also, it is very common for subclass to override super class `hashValue`. Supposing opposite, if we also have another class called `class Banana:Fruit`, we may get the result that an `Apple` is equals to a `Banana`, using `Fruit`,  just because they have the same `hashValue`.</div><div class="gmail_default" style="font-family:georgia,serif"><br></div><div class="gmail_default" style="font-family:georgia,serif">If we stick to the super class `hashValue`, we may also not get the differences between instances of a certain subclass. For example, we may get the result that a `redApple` equals to a `greenApple`.</div><div class="gmail_default" style="font-family:georgia,serif"><br></div><div class="gmail_default" style="font-family:georgia,serif">So in my option, if one instance equals to another instance, the foundation should be that the `type(of:instance)` equals. If you want to enlarge the type to their super class, you need to be careful, as they are not guaranteed automatically.</div><div class="gmail_default" style="font-family:georgia,serif"><br></div><div class="gmail_default" style="font-family:georgia,serif">Zhaoxin</div></div><div class="gmail_extra"><br><div class="gmail_quote">On Fri, Sep 2, 2016 at 7:32 AM, Jordan Rose <span dir="ltr">&lt;<a href="mailto:jordan_rose@apple.com" target="_blank">jordan_rose@apple.com</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word"><div>The <a href="https://en.wikipedia.org/wiki/Liskov_substitution_principle" target="_blank">Liskov substitution principle</a> says that a B should always be able to be treated like an A. Your Set&lt;A&gt; may <i>already</i> contain Bs, even without them ever being statically typed as B. If you think A and B are unrelated types, you should be using composition rather than inheritance.</div><div><br></div><div>If a subclass overrides hashValue, they must be in a position to affect == as well, and it must work no matter which object is on the left-hand side. NSObject does this by having == call the isEqual(_:) method, but you still need to design your class hierarchy and isEqual(_:) methods carefully.</div><span><font color="#888888"><div><br></div><div>Jordan</div></font></span><div><div><div><br></div><br><div><blockquote type="cite"><div>On Sep 1, 2016, at 16:28, Zhao Xin &lt;<a href="mailto:owenzx@gmail.com" target="_blank">owenzx@gmail.com</a>&gt; wrote:</div><br><div><div dir="ltr"><div class="gmail_default" style="font-family:georgia,serif">I believe if B inherits A, they are not the same type. So the rule doesn&#39;t apply here.</div><div class="gmail_default" style="font-family:georgia,serif"><br></div><div class="gmail_default" style="font-family:georgia,serif">Zhaoxin</div></div><div class="gmail_extra"><br><div class="gmail_quote">On Fri, Sep 2, 2016 at 7:02 AM, Nick Brook <span dir="ltr">&lt;<a href="mailto:nrbrook@gmail.com" target="_blank">nrbrook@gmail.com</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word">Hi Jordan,<div><br></div><div>Thanks for the advice.</div><div><br></div><div>What if a subclass does implement hashValue differently? It seems you are saying a subclass should never override hashValue? Should Set not compare elements with == instead of hashValue?<br><div><br></div><div>
Thanks<br><span style="font-family:Helvetica;font-size:12px;font-style:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;float:none;display:inline!important">Nick</span><br style="font-family:Helvetica;font-size:12px;font-style:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><br style="font-family:Helvetica;font-size:12px;font-style:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><span style="font-family:Helvetica;font-size:12px;font-style:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;float:none;display:inline!important">M: <a href="tel:%2B44%20%280%297986%20048%20141" value="+447986048141" target="_blank">+44 (0)7986 048 141</a></span><div style="font-family:Helvetica;font-size:12px;font-style:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">W: <a href="http://nickbrook.me/" target="_blank">http://nickbrook.me</a></div>
</div><div><div>
<br><div><blockquote type="cite"><div>On 1 Sep 2016, at 23:55, Jordan Rose &lt;<a href="mailto:jordan_rose@apple.com" target="_blank">jordan_rose@apple.com</a>&gt; wrote:</div><br><div><div style="font-family:Helvetica;font-size:12px;font-style:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><blockquote type="cite"><div><br>On Sep 1, 2016, at 15:44, Zhao Xin via swift-users &lt;<a href="mailto:swift-users@swift.org" target="_blank">swift-users@swift.org</a>&gt; wrote:</div><br><div><div dir="ltr"><div class="gmail_default" style="font-family:georgia,serif">Hi Nick,</div><div class="gmail_default" style="font-family:georgia,serif"><br></div><div class="gmail_default" style="font-family:georgia,serif">Glad to help.</div><div class="gmail_default" style="font-family:georgia,serif"><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">but when using third party classes I don’t know if the hash values are comparable<br></blockquote><div><br></div><div class="gmail_default" style="font-family:georgia,serif">You can create an extension with a convenient init(:), which creates a new instance of  the super class basing on the instance of the sub class. That will guarantee the subtraction. Below code works in Xcode 7.3.1 with Swift 2.2.<br></div><div class="gmail_default" style="font-family:georgia,serif"><br></div><div class="gmail_default"><div style="font-family:menlo;margin:0px;font-size:11px;line-height:normal"><span style="color:rgb(187,44,162)">import</span><span><span> </span>Foundation</span></div><div style="font-family:menlo;margin:0px;font-size:11px;line-height:normal;min-height:13px"><span></span><br></div><div style="font-family:menlo;margin:0px;font-size:11px;line-height:normal"><span style="color:rgb(187,44,162)">func</span><span><span> </span>==(lhs:<span> </span></span><span style="color:rgb(79,129,135)">Foo</span><span>, rhs:<span> </span></span><span style="color:rgb(79,129,135)">Foo</span><span>) -&gt;<span> </span></span><span style="color:rgb(112,61,170)">Bool</span><span><span> </span>{</span></div><div style="font-family:menlo;margin:0px;font-size:11px;line-height:normal"><span>   <span> </span></span><span style="color:rgb(187,44,162)">return</span><span><span> </span>lhs.</span><span style="color:rgb(79,129,135)">id</span><span><span> </span>== rhs.</span><span style="color:rgb(79,129,135)">id</span></div><div style="font-family:menlo;margin:0px;font-size:11px;line-height:normal"><span>}</span></div><div style="font-family:menlo;margin:0px;font-size:11px;line-height:normal;min-height:13px"><span></span><br></div><div style="font-family:menlo;margin:0px;font-size:11px;line-height:normal;color:rgb(112,61,170)"><span style="color:rgb(187,44,162)">class</span><span><span> </span>Foo:</span><span>Hashable</span><span><span> </span>{</span></div><div style="font-family:menlo;margin:0px;font-size:11px;line-height:normal"><span>   <span> </span></span><span style="color:rgb(187,44,162)">let</span><span><span> </span>id:</span><span style="color:rgb(112,61,170)">Int</span></div><div style="font-family:menlo;margin:0px;font-size:11px;line-height:normal"><span>   <span> </span></span><span style="color:rgb(187,44,162)">var</span><span><span> </span>hashValue:<span> </span></span><span style="color:rgb(112,61,170)">Int</span><span><span> </span>{</span></div><div style="font-family:menlo;margin:0px;font-size:11px;line-height:normal"><span>       <span> </span></span><span style="color:rgb(187,44,162)">return</span><span><span> </span></span><span style="color:rgb(79,129,135)">id</span></div><div style="font-family:menlo;margin:0px;font-size:11px;line-height:normal"><span>    }</span></div><div style="font-family:menlo;margin:0px;font-size:11px;line-height:normal;min-height:13px"><span>    </span><br></div><div style="font-family:menlo;margin:0px;font-size:11px;line-height:normal"><span>   <span> </span></span><span style="color:rgb(187,44,162)">required</span><span><span> </span></span><span style="color:rgb(187,44,162)">init</span><span>(</span><span style="color:rgb(187,44,162)">_</span><span><span> </span>id:</span><span style="color:rgb(112,61,170)">Int</span><span>) {</span></div><div style="font-family:menlo;margin:0px;font-size:11px;line-height:normal"><span>       <span> </span></span><span style="color:rgb(187,44,162)">self</span><span>.</span><span style="color:rgb(79,129,135)">id</span><span><span> </span>= id</span></div><div style="font-family:menlo;margin:0px;font-size:11px;line-height:normal"><span>    }</span></div><div style="font-family:menlo;margin:0px;font-size:11px;line-height:normal"><span>}</span></div><div style="font-family:menlo;margin:0px;font-size:11px;line-height:normal;min-height:13px"><span></span><br></div><div style="font-family:menlo;margin:0px;font-size:11px;line-height:normal"><span style="color:rgb(187,44,162)">class</span><span><span> </span>Bar:</span><span style="color:rgb(79,129,135)">Foo</span><span><span> </span>{</span></div><div style="font-family:menlo;margin:0px;font-size:11px;line-height:normal"><span>   <span> </span></span><span style="color:rgb(187,44,162)">override</span><span><span> </span></span><span style="color:rgb(187,44,162)">var</span><span><span> </span>hashValue:<span> </span></span><span style="color:rgb(112,61,170)">Int</span><span><span> </span><wbr>{</span></div><div style="font-family:menlo;margin:0px;font-size:11px;line-height:normal"><span>       <span> </span></span><span style="color:rgb(187,44,162)">return</span><span><span> </span></span><span style="color:rgb(79,129,135)">id</span><span><span> </span>*<span> </span></span><span style="color:rgb(39,42,216)">5</span></div><div style="font-family:menlo;margin:0px;font-size:11px;line-height:normal"><span>    }</span></div><div style="font-family:menlo;margin:0px;font-size:11px;line-height:normal"><span>}</span></div><div style="font-family:menlo;margin:0px;font-size:11px;line-height:normal;min-height:13px"><span></span><br></div><div style="font-family:menlo;margin:0px;font-size:11px;line-height:normal"><span style="color:rgb(187,44,162)">var</span><span><span> </span>fooSet:</span><span style="color:rgb(112,61,170)">Set</span><span>&lt;</span><span style="color:rgb(79,129,135)">Foo</span><span>&gt; = [</span><span style="color:rgb(79,129,135)">Foo</span><span>(</span><span style="color:rgb(39,42,216)">10</span><span>),<span> </span></span><span style="color:rgb(79,129,135)">Foo</span><span>(</span><span style="color:rgb(39,42,216)">9</span><span>),<span> </span></span><span style="color:rgb(79,129,135)">Foo</span><span>(</span><span style="color:rgb(39,42,216)">8</span><span>),<span> </span></span><span style="color:rgb(79,129,135)">Foo</span><span>(</span><span style="color:rgb(39,42,216)"><wbr>7</span><span>)]</span></div><div style="font-family:menlo;margin:0px;font-size:11px;line-height:normal"><span style="color:rgb(187,44,162)">var</span><span><span> </span>barSet:</span><span style="color:rgb(112,61,170)">Set</span><span>&lt;</span><span style="color:rgb(79,129,135)">Bar</span><span>&gt; = [</span><span style="color:rgb(79,129,135)">Bar</span><span>(</span><span style="color:rgb(39,42,216)">8</span><span>),<span> </span></span><span style="color:rgb(79,129,135)">Bar</span><span>(</span><span style="color:rgb(39,42,216)">7</span><span>),<span> </span></span><span style="color:rgb(79,129,135)">Bar</span><span>(</span><span style="color:rgb(39,42,216)">6</span><span>),<span> </span></span><span style="color:rgb(79,129,135)">Bar</span><span>(</span><span style="color:rgb(39,42,216)">5</span><span><wbr>)]</span></div><div style="font-family:menlo;margin:0px;font-size:11px;line-height:normal;min-height:13px"><span></span><br></div><div style="font-family:menlo;margin:0px;font-size:11px;line-height:normal;color:rgb(0,132,0)"><span>//fooSet.subtract(barSet) // error: cannot invoke &#39;subtract&#39; with an argument list of type &#39;(Set&lt;Bar&gt;)&#39;</span></div><div style="font-family:menlo;margin:0px;font-size:11px;line-height:normal;color:rgb(79,129,135)"><span>fooSet</span><span><span> </span>=<span> </span></span><span>fooSet</span><span>.</span><span style="color:rgb(61,29,129)">subtract</span><span>(</span><span>barSe<wbr>t</span><span><span> </span></span><span style="color:rgb(187,44,162)">as</span><span><span> </span></span><span style="color:rgb(112,61,170)">Set</span><span>&lt;</span><span>Foo</span><span>&gt;) </span><span style="color:rgb(0,132,0);font-family:menlo">// works, but not what we want</span></div><div style="font-family:menlo;margin:0px;font-size:11px;line-height:normal"><span style="color:rgb(79,129,135)">fooSet</span><span>.</span><span style="color:rgb(61,29,129)">forEach</span><span><span> </span>{<span> </span></span><span style="color:rgb(61,29,129)">print</span><span>(</span><span style="color:rgb(209,47,27)">&quot;</span><span>\</span><span style="color:rgb(209,47,27)">(</span><span>$0.</span><span style="color:rgb(187,44,162)">d<wbr>ynamicType</span><span style="color:rgb(209,47,27)">), id:</span><span>\</span><span style="color:rgb(209,47,27)">(</span><span>$0.</span><span style="color:rgb(79,129,135)">id</span><span style="color:rgb(209,47,27)">)&quot;</span><span>) }</span></div><div style="font-family:menlo;margin:0px;font-size:11px;line-height:normal;color:rgb(0,132,0)"><span>/*</span></div><div style="font-family:menlo;margin:0px;font-size:11px;line-height:normal;color:rgb(0,132,0)"><span> Foo, id:7</span></div><div style="font-family:menlo;margin:0px;font-size:11px;line-height:normal;color:rgb(0,132,0)"><span> Foo, id:10</span></div><div style="font-family:menlo;margin:0px;font-size:11px;line-height:normal;color:rgb(0,132,0)"><span> Foo, id:9</span></div><div style="font-family:menlo;margin:0px;font-size:11px;line-height:normal;color:rgb(0,132,0)"><span>*/</span></div></div></div></div></blockquote><br></div><div style="font-family:Helvetica;font-size:12px;font-style:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">This isn&#39;t really a sensible thing to do. The rules for Hashable require that `a == b` implies `a.hashValue == b.hashValue`, and `a.hashValue != b.hashValue` implies `a != b`. If you break these rules you&#39;re going to have problems no matter what static types you&#39;re using.</div><div style="font-family:Helvetica;font-size:12px;font-style:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><br></div><div style="font-family:Helvetica;font-size:12px;font-style:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">Upcasting from Set&lt;Bar&gt; to Set&lt;Foo&gt; is the most concise way to solve this problem.</div><div style="font-family:Helvetica;font-size:12px;font-style:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><br></div><div style="font-family:Helvetica;font-size:12px;font-style:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">Jordan</div></div></blockquote></div><br></div></div></div></div></blockquote></div><br></div>
</div></blockquote></div><br></div></div></div></blockquote></div><br></div>
</div></blockquote></div><br></div></div></div></blockquote></div><br></div>