Today, I encountered a strange trouble with higher-rank polymorphism. It was finally solved by nominal typing. Was it a bug in type checker? lack of power in type inference? or lack of my understanding? I&#39;ll submit this in hope that it will at least result in better GHC error message some day: <br>

<br>My following code<br><br><a href="https://github.com/sugoi/sugoi/blob/0aec19b29274ddb7c5ae46b9b733e91bae0790b2/Sugoi/Types.hs">https://github.com/sugoi/sugoi/blob/0aec19b29274ddb7c5ae46b9b733e91bae0790b2/Sugoi/Types.hs</a><br clear="all">

<pre><div class="" id="LC37"><span class="">&gt; runDB</span> <span class="">::</span> <span class="">Lens</span> <span class="">NetworkState</span> <span class="">RIB</span></div><div class="" id="LC38"><span class="">&gt; runDB</span> <span class="">=</span> <span class="">lens</span> <span class="">(</span><span class="">f</span><span class="">::</span><span class="">NetworkState</span> <span class="">-&gt;</span> <span class="">RIB</span><span class="">)</span> <span class="">(</span><span class="">\</span><span class="">x</span> <span class="">s</span> <span class="">-&gt;</span> <span class="">s</span> <span class="">{</span> <span class="">_runDB</span> <span class="">=</span> <span class="">x</span> <span class="">})</span> </div>

<div class="" id="LC39">&gt;  <span class="">where</span> <span class="">f</span> <span class="">::</span> <span class="">NetworkState</span> <span class="">-&gt;</span> <span class="">RIB</span></div></pre>Didn&#39;t typecheck with following error:<br>

<br>Sugoi/Types.hs:38:15:<br>    Couldn&#39;t match expected type `RIB&#39;<br>                with actual type `DB.DBMT (Maybe Int) IO a0<br>                                  -&gt; IO (StM (DB.DBMT (Maybe Int) IO) a0)&#39;<br>

    Expected type: NetworkState -&gt; RIB<br>      Actual type: NetworkState<br>                   -&gt; DB.DBMT (Maybe Int) IO a0<br>                   -&gt; IO (StM (DB.DBMT (Maybe Int) IO) a0)<br>    In the first argument of `lens&#39;, namely<br>

      `(f :: NetworkState -&gt; RIB)&#39;<br>    In the expression:<br>      lens (f :: NetworkState -&gt; RIB) (\ x s -&gt; s {_runDB = x})<br><br><br>How come an expression `(f :: NetworkState -&gt; RIB)&#39; is not of type NetworkState -&gt; RIB ?<br>

When I changed the definition of runDB as follows,<br><br>&gt; runDB = lens (\NetworkState{_runDB = x} -&gt; x) (\x s -&gt; s { _runDB = x }) <br><br>The source of error was more clear:<br><br>    Expected type: DB.DBMT (Maybe Int) IO a1<br>

                   -&gt; IO (StM (DB.DBMT (Maybe Int) IO) a1)<br>      Actual type: DB.DBMT (Maybe Int) IO a<br>                   -&gt; IO (StM (DB.DBMT (Maybe Int) IO) a)<br><br>So, ghc couldn&#39;t unify these two types. By using the nominal typing, namely<br>

<br>&gt; - type RIB = RunInBase (DB.DBMT (Maybe Int) IO) IO<br>
&gt; + newtype RIB = RIB (RunInBase (DB.DBMT (Maybe Int) IO) IO)<br>
<br>the problem was solved.<br><br>Always grateful to haskell-cafe from being there,<br>-- <br>Takayuki MURANUSHI<br>The Hakubi Center for Advanced Research, Kyoto University<br><a href="http://www.hakubi.kyoto-u.ac.jp/02_mem/h22/muranushi.html" target="_blank">http://www.hakubi.kyoto-u.ac.jp/02_mem/h22/muranushi.html</a><br>