What was wrong with SML?
I&#x27;m not really convinced by the author&#x27;s first example. While an element of type bool is an instance of type a, an element of type bool -&gt; bool is <i>not</i> an instance of type a -&gt; a.<p>The issue is precisely an issue of variance, which is mentioned in reference to Scala, but somehow it&#x27;s glossed over. The type a -&gt; a is covariant in its second argument, but contravariant in its first argument. As a result, you cannot &quot;specialize&quot; it to bool -&gt; bool, because specialization is really another name for covariance.<p>Another name for contravariance is &quot;generalization&quot;. If you ask for something of type &quot;bool -&gt; b&quot;, and someone provides you with some function f of type &quot;a -&gt; b&quot;, then you&#x27;re happy. The map f is indeed an instance of &quot;bool -&gt; b&quot;: it can eat anything, so it can eat booleans. But with type a -&gt; a, you cannot do what I just did: type &quot;a&quot; is already the most general one, and you cannot do better.<p>If SML accepted something of type &quot;bool -&gt; bool&quot; for an instance of type &quot;a -&gt; a&quot;, then it was a fundamental error. But this doesn&#x27;t mean that the whole thing should have been thrown out and replaced with monads. In fact, I don&#x27;t really get how monads have anything to do with the problem at hand. If Haskell can prevent the following code, then I don&#x27;t see why SML couldn&#x27;t have prevented the authors&#x27; code:<p><pre><code>    do m &lt;- STRef id
       m &lt;- not
       m 42</code></pre>