<?xml version="1.0" encoding="UTF-8"?><feed xmlns="http://www.w3.org/2005/Atom"><title xmlns:ns="http://www.w3.org/2005/Atom" ns:type="text">Static analyzer wishlist – Haskell – Aelve Guide</title><id>https://guide.aelve.com/haskell/feed/category/lbbp2xa6</id><updated>2017-08-06T23:41:52Z</updated><link xmlns:ns="http://www.w3.org/2005/Atom" ns:href="https://guide.aelve.com/haskell/feed/category/lbbp2xa6"/><entry><id>vz9kl65l</id><title xmlns:ns="http://www.w3.org/2005/Atom" ns:type="text">Writing into &#39;ix&#39;</title><updated>2017-08-06T23:41:52Z</updated><content xmlns:ns="http://www.w3.org/2005/Atom" ns:type="html">&lt;h1&gt;  &lt;span class=&#34;item-name&#34;&gt;Writing into &amp;#39;ix&amp;#39;&lt;/span&gt;

&lt;/h1&gt;&lt;p&gt;Sometimes people forget that if they write into &lt;code&gt;ix&lt;/code&gt; from &lt;a href=&#34;https://hackage.haskell.org/package/lens&#34;&gt;lens&lt;/a&gt;, the corresponding element does not get created if it didn&#39;t exist already. Thus, this (and variants of this) are wrong:&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34;&gt;&lt;pre class=&#34;sourceCode&#34;&gt;&lt;code class=&#34;sourceCode&#34;&gt;&lt;span class=&#34;kw&#34;&gt;do&lt;/span&gt; absent &lt;span class=&#34;ot&#34;&gt;&amp;lt;-&lt;/span&gt; isNothing &lt;span class=&#34;fu&#34;&gt;&amp;lt;$&amp;gt;&lt;/span&gt; preuse (ix k)
   when absent &lt;span class=&#34;fu&#34;&gt;$&lt;/span&gt; ix k &lt;span class=&#34;fu&#34;&gt;.=&lt;/span&gt; blah&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
</content><link xmlns:ns="http://www.w3.org/2005/Atom" ns:href="https://guide.aelve.com/haskell/static-analyzer-wishlist-lbbp2xa6#item-vz9kl65l"/></entry><entry><id>atwtiaob</id><title xmlns:ns="http://www.w3.org/2005/Atom" ns:type="text">Infinite loops in instances</title><updated>2017-08-06T23:33:36Z</updated><content xmlns:ns="http://www.w3.org/2005/Atom" ns:type="html">&lt;h1&gt;  &lt;span class=&#34;item-name&#34;&gt;Infinite loops in instances&lt;/span&gt;

&lt;/h1&gt;&lt;p&gt;This is almost always a mistake (and unfortunately it&#39;s more common than it might seem):&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34;&gt;&lt;pre class=&#34;sourceCode&#34;&gt;&lt;code class=&#34;sourceCode&#34;&gt;&lt;span class=&#34;kw&#34;&gt;instance&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Foo&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Int&lt;/span&gt; &lt;span class=&#34;kw&#34;&gt;where&lt;/span&gt; 
  foo &lt;span class=&#34;fu&#34;&gt;=&lt;/span&gt; foo&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;It should also be possible to detect a trickier variant of this mistake. Here &lt;code&gt;f&lt;/code&gt; is a function (or chain of functions) that doesn&#39;t change the type:&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34;&gt;&lt;pre class=&#34;sourceCode&#34;&gt;&lt;code class=&#34;sourceCode&#34;&gt;&lt;span class=&#34;kw&#34;&gt;instance&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Foo&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Int&lt;/span&gt; &lt;span class=&#34;kw&#34;&gt;where&lt;/span&gt;
  foo &lt;span class=&#34;fu&#34;&gt;=&lt;/span&gt; f &lt;span class=&#34;fu&#34;&gt;.&lt;/span&gt; foo&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&#34;sourceCode&#34;&gt;&lt;pre class=&#34;sourceCode&#34;&gt;&lt;code class=&#34;sourceCode&#34;&gt;&lt;span class=&#34;kw&#34;&gt;instance&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Foo&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Int&lt;/span&gt; &lt;span class=&#34;kw&#34;&gt;where&lt;/span&gt;
  foo &lt;span class=&#34;fu&#34;&gt;=&lt;/span&gt; foo &lt;span class=&#34;fu&#34;&gt;.&lt;/span&gt; f&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
</content><link xmlns:ns="http://www.w3.org/2005/Atom" ns:href="https://guide.aelve.com/haskell/static-analyzer-wishlist-lbbp2xa6#item-atwtiaob"/></entry><entry><id>ly8ahto1</id><title xmlns:ns="http://www.w3.org/2005/Atom" ns:type="text">[0..length xs]</title><updated>2017-08-06T23:28:27Z</updated><content xmlns:ns="http://www.w3.org/2005/Atom" ns:type="html">&lt;h1&gt;  &lt;span class=&#34;item-name&#34;&gt;[0..length xs]&lt;/span&gt;

&lt;/h1&gt;&lt;p&gt;People often write &lt;code&gt;[0..length xs]&lt;/code&gt; when they intend to write &lt;code&gt;[0..length xs - 1]&lt;/code&gt;.&lt;/p&gt;
</content><link xmlns:ns="http://www.w3.org/2005/Atom" ns:href="https://guide.aelve.com/haskell/static-analyzer-wishlist-lbbp2xa6#item-ly8ahto1"/></entry><entry><id>a6upne3h</id><title xmlns:ns="http://www.w3.org/2005/Atom" ns:type="text">Buggy serialization instances</title><updated>2017-08-06T23:25:18Z</updated><content xmlns:ns="http://www.w3.org/2005/Atom" ns:type="html">&lt;h1&gt;  &lt;span class=&#34;item-name&#34;&gt;Buggy serialization instances&lt;/span&gt;

&lt;/h1&gt;&lt;p&gt;&lt;code&gt;Binary&lt;/code&gt; instances are usually written like this:&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34;&gt;&lt;pre class=&#34;sourceCode&#34;&gt;&lt;code class=&#34;sourceCode&#34;&gt;data Foo = Foo {this, that, other :: Int}

instance Binary Foo where
  put Foo{..) = put that &amp;gt;&amp;gt; put this &amp;gt;&amp;gt; put other
  get = Foo &amp;lt;$&amp;gt; get &amp;lt;*&amp;gt; get &amp;lt;*&amp;gt; get&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Here the order was mixed-up: we serialize &lt;code&gt;that, this, other&lt;/code&gt;, but deserialize &lt;code&gt;this, that, other&lt;/code&gt; (&lt;code&gt;this&lt;/code&gt; and &lt;code&gt;that&lt;/code&gt; are swapped).&lt;/p&gt;
&lt;p&gt;Another, similar, bug is forgetting to serialize one of the fields altogether.&lt;/p&gt;
</content><link xmlns:ns="http://www.w3.org/2005/Atom" ns:href="https://guide.aelve.com/haskell/static-analyzer-wishlist-lbbp2xa6#item-a6upne3h"/></entry><entry><id>tdzpwqbw</id><title xmlns:ns="http://www.w3.org/2005/Atom" ns:type="text">&#39;length&#39;, &#39;null&#39;, etc applied to tuples</title><updated>2017-08-06T23:23:43Z</updated><content xmlns:ns="http://www.w3.org/2005/Atom" ns:type="html">&lt;h1&gt;  &lt;span class=&#34;item-name&#34;&gt;&amp;#39;length&amp;#39;, &amp;#39;null&amp;#39;, etc applied to tuples&lt;/span&gt;

&lt;/h1&gt;&lt;p&gt;You almost never want to apply &lt;code&gt;length&lt;/code&gt; or &lt;code&gt;null&lt;/code&gt; (and most other &lt;code&gt;Foldable&lt;/code&gt; methods) to tuples because they treat tuples as one-element containers. So, when an application of one of those methods is detected, it&#39;s likely a bug.&lt;/p&gt;
</content><link xmlns:ns="http://www.w3.org/2005/Atom" ns:href="https://guide.aelve.com/haskell/static-analyzer-wishlist-lbbp2xa6#item-tdzpwqbw"/></entry><entry><id>o8urig1a</id><title xmlns:ns="http://www.w3.org/2005/Atom" ns:type="text">Warn about unexpectedly slow functions</title><updated>2017-08-06T23:19:06Z</updated><content xmlns:ns="http://www.w3.org/2005/Atom" ns:type="html">&lt;h1&gt;  &lt;span class=&#34;item-name&#34;&gt;Warn about unexpectedly slow functions&lt;/span&gt;

&lt;/h1&gt;&lt;p&gt;&lt;code&gt;Data.HashMap.(Strict|Lazy).size&lt;/code&gt; and &lt;code&gt;Data.HashSet.size&lt;/code&gt; are O(n), which is surprising to many people because corresponding functions for ordinary maps and sets are fast. It would be good to detect when it can likely lead to performance problems and emit a warning.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Data.Text.index&lt;/code&gt; and &lt;code&gt;Data.Text.length&lt;/code&gt; are in the same category, by the way.&lt;/p&gt;
</content><link xmlns:ns="http://www.w3.org/2005/Atom" ns:href="https://guide.aelve.com/haskell/static-analyzer-wishlist-lbbp2xa6#item-o8urig1a"/></entry><entry><id>u5k4yspk</id><title xmlns:ns="http://www.w3.org/2005/Atom" ns:type="text">Potential infinite recursion</title><updated>2017-08-06T23:15:04Z</updated><content xmlns:ns="http://www.w3.org/2005/Atom" ns:type="html">&lt;h1&gt;  &lt;span class=&#34;item-name&#34;&gt;Potential infinite recursion&lt;/span&gt;

&lt;/h1&gt;&lt;p&gt;Here&#39;s a case where an infinite loop could happen because the &lt;code&gt;n &amp;lt; 0&lt;/code&gt; case wasn&#39;t handled:&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34;&gt;&lt;pre class=&#34;sourceCode&#34;&gt;&lt;code class=&#34;sourceCode&#34;&gt;&lt;span class=&#34;ot&#34;&gt;f ::&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Int&lt;/span&gt; &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt; something
f n &lt;span class=&#34;fu&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;fu&#34;&gt;...&lt;/span&gt; f (n&lt;span class=&#34;fu&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;dv&#34;&gt;1&lt;/span&gt;) &lt;span class=&#34;fu&#34;&gt;...&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;In some cases it&#39;s going to be a false positive, but it&#39;s still better to report such cases.&lt;/p&gt;
</content><link xmlns:ns="http://www.w3.org/2005/Atom" ns:href="https://guide.aelve.com/haskell/static-analyzer-wishlist-lbbp2xa6#item-u5k4yspk"/></entry><entry><id>epo2vc2q</id><title xmlns:ns="http://www.w3.org/2005/Atom" ns:type="text">Modifying state in MonadBaseControl</title><updated>2017-08-05T20:01:39Z</updated><content xmlns:ns="http://www.w3.org/2005/Atom" ns:type="html">&lt;h1&gt;  &lt;span class=&#34;item-name&#34;&gt;Modifying state in MonadBaseControl&lt;/span&gt;

&lt;/h1&gt;&lt;p&gt;When you use e.g. &lt;a href=&#34;https://hackage.haskell.org/package/lifted-base/docs/Control-Exception-Lifted.html#v:bracket&#34;&gt;&lt;code&gt;bracket&lt;/code&gt;&lt;/a&gt; from &lt;a href=&#34;https://hackage.haskell.org/package/lifted-base&#34;&gt;lifted-base&lt;/a&gt;, and you do anything with &lt;code&gt;State&lt;/code&gt;, &lt;code&gt;Writer&lt;/code&gt;, etc in the release action, it will be discarded. Thus, when a release action explicitly modifies state, it&#39;s likely a mistake and the developer simply doesn&#39;t know that it&#39;s not safe to do. An example:&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34;&gt;&lt;pre class=&#34;sourceCode&#34;&gt;&lt;code class=&#34;sourceCode&#34;&gt;bracket &lt;span class=&#34;fu&#34;&gt;...&lt;/span&gt; (\a &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt; put (a, &lt;span class=&#34;dv&#34;&gt;0&lt;/span&gt;)) &lt;span class=&#34;fu&#34;&gt;$&lt;/span&gt; &lt;span class=&#34;kw&#34;&gt;do&lt;/span&gt;
  &lt;span class=&#34;fu&#34;&gt;...&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
</content><link xmlns:ns="http://www.w3.org/2005/Atom" ns:href="https://guide.aelve.com/haskell/static-analyzer-wishlist-lbbp2xa6#item-epo2vc2q"/></entry><entry><id>f6sd83os</id><title xmlns:ns="http://www.w3.org/2005/Atom" ns:type="text">Using Data.ByteString.Char8.pack</title><updated>2017-08-05T19:55:13Z</updated><content xmlns:ns="http://www.w3.org/2005/Atom" ns:type="html">&lt;h1&gt;  &lt;span class=&#34;item-name&#34;&gt;Using Data.ByteString.Char8.pack&lt;/span&gt;

&lt;/h1&gt;&lt;p&gt;Using &lt;code&gt;BS8.pack&lt;/code&gt; is almost always a mistake, because it messes up any Unicode characters. Instead you probably want to encode the string into UTF-8 (with e.g. &lt;a href=&#34;https://hackage.haskell.org/package/utf8-string&#34;&gt;utf8-string&lt;/a&gt; or &lt;a href=&#34;https://hackage.haskell.org/package/text&#34;&gt;text&lt;/a&gt;).&lt;/p&gt;
</content><link xmlns:ns="http://www.w3.org/2005/Atom" ns:href="https://guide.aelve.com/haskell/static-analyzer-wishlist-lbbp2xa6#item-f6sd83os"/></entry><entry><id>kq253wsj</id><title xmlns:ns="http://www.w3.org/2005/Atom" ns:type="text">Weird boolean computations</title><updated>2017-08-05T19:41:15Z</updated><content xmlns:ns="http://www.w3.org/2005/Atom" ns:type="html">&lt;h1&gt;  &lt;span class=&#34;item-name&#34;&gt;Weird boolean computations&lt;/span&gt;

&lt;/h1&gt;&lt;p&gt;These are often copypaste errors:&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34;&gt;&lt;pre class=&#34;sourceCode&#34;&gt;&lt;code class=&#34;sourceCode&#34;&gt;a &lt;span class=&#34;fu&#34;&gt;||&lt;/span&gt; (a &lt;span class=&#34;fu&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; b)    &lt;span class=&#34;fu&#34;&gt;==&amp;gt;&lt;/span&gt;    a
a &lt;span class=&#34;fu&#34;&gt;||&lt;/span&gt; not a       &lt;span class=&#34;fu&#34;&gt;==&amp;gt;&lt;/span&gt;    &lt;span class=&#34;dt&#34;&gt;True&lt;/span&gt;
a &lt;span class=&#34;fu&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; (a &lt;span class=&#34;fu&#34;&gt;||&lt;/span&gt; b)    &lt;span class=&#34;fu&#34;&gt;==&amp;gt;&lt;/span&gt;    a
a &lt;span class=&#34;fu&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; not a       &lt;span class=&#34;fu&#34;&gt;==&amp;gt;&lt;/span&gt;    &lt;span class=&#34;dt&#34;&gt;False&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Even if not, they still could be simplified.&lt;/p&gt;
</content><link xmlns:ns="http://www.w3.org/2005/Atom" ns:href="https://guide.aelve.com/haskell/static-analyzer-wishlist-lbbp2xa6#item-kq253wsj"/></entry><entry><id>catcmmrx</id><title xmlns:ns="http://www.w3.org/2005/Atom" ns:type="text">Using &#39;pure&#39; or &#39;return&#39; in the middle of a function</title><updated>2017-08-05T19:38:01Z</updated><content xmlns:ns="http://www.w3.org/2005/Atom" ns:type="html">&lt;h1&gt;  &lt;span class=&#34;item-name&#34;&gt;Using &amp;#39;pure&amp;#39; or &amp;#39;return&amp;#39; in the middle of a function&lt;/span&gt;

&lt;/h1&gt;&lt;p&gt;An inexperienced developer might write this, thinking that &lt;code&gt;return&lt;/code&gt; means “early exit”. It doesn&#39;t.&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34;&gt;&lt;pre class=&#34;sourceCode&#34;&gt;&lt;code class=&#34;sourceCode&#34;&gt;main &lt;span class=&#34;fu&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kw&#34;&gt;do&lt;/span&gt;
  &lt;span class=&#34;fu&#34;&gt;...&lt;/span&gt;
  when p &lt;span class=&#34;fu&#34;&gt;$&lt;/span&gt; return ()
  &lt;span class=&#34;fu&#34;&gt;...&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
</content><link xmlns:ns="http://www.w3.org/2005/Atom" ns:href="https://guide.aelve.com/haskell/static-analyzer-wishlist-lbbp2xa6#item-catcmmrx"/></entry><entry><id>fydta0b5</id><title xmlns:ns="http://www.w3.org/2005/Atom" ns:type="text">Using (&lt;/&gt;) with URLs</title><updated>2017-08-05T19:35:35Z</updated><content xmlns:ns="http://www.w3.org/2005/Atom" ns:type="html">&lt;h1&gt;  &lt;span class=&#34;item-name&#34;&gt;Using (&amp;lt;/&amp;gt;) with URLs&lt;/span&gt;

&lt;/h1&gt;&lt;p&gt;This will fail on Windows because &lt;code&gt;&amp;lt;/&amp;gt;&lt;/code&gt; will append &lt;code&gt;&amp;quot;\&amp;quot;&lt;/code&gt;, not &lt;code&gt;&amp;quot;/&amp;quot;&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34;&gt;&lt;pre class=&#34;sourceCode&#34;&gt;&lt;code class=&#34;sourceCode&#34;&gt;foo &lt;span class=&#34;fu&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;st&#34;&gt;&amp;quot;https://example.com/get&amp;quot;&lt;/span&gt; &lt;span class=&#34;fu&#34;&gt;&amp;lt;/&amp;gt;&lt;/span&gt; show a&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
</content><link xmlns:ns="http://www.w3.org/2005/Atom" ns:href="https://guide.aelve.com/haskell/static-analyzer-wishlist-lbbp2xa6#item-fydta0b5"/></entry><entry><id>daxahxjp</id><title xmlns:ns="http://www.w3.org/2005/Atom" ns:type="text">Floated-out lists</title><updated>2017-08-05T19:11:30Z</updated><content xmlns:ns="http://www.w3.org/2005/Atom" ns:type="html">&lt;h1&gt;  &lt;span class=&#34;item-name&#34;&gt;Floated-out lists&lt;/span&gt;

&lt;/h1&gt;&lt;p&gt;GHC will needlessly share &lt;code&gt;[1..10000000]&lt;/code&gt; between two computations and cause a memory leak here:&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34;&gt;&lt;pre class=&#34;sourceCode&#34;&gt;&lt;code class=&#34;sourceCode&#34;&gt;foo &lt;span class=&#34;fu&#34;&gt;=&lt;/span&gt; for_ [&lt;span class=&#34;dv&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;fu&#34;&gt;..&lt;/span&gt;&lt;span class=&#34;dv&#34;&gt;10000000&lt;/span&gt;] &lt;span class=&#34;fu&#34;&gt;$&lt;/span&gt; \i &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt;
  &lt;span class=&#34;fu&#34;&gt;...&lt;/span&gt;

bar &lt;span class=&#34;fu&#34;&gt;=&lt;/span&gt; for_ [&lt;span class=&#34;dv&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;fu&#34;&gt;..&lt;/span&gt;&lt;span class=&#34;dv&#34;&gt;10000000&lt;/span&gt;] &lt;span class=&#34;fu&#34;&gt;$&lt;/span&gt; \k &lt;span class=&#34;ot&#34;&gt;-&amp;gt;&lt;/span&gt;
  &lt;span class=&#34;fu&#34;&gt;...&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The solution is to use something like &lt;a href=&#34;https://hackage.haskell.org/package/loop&#34;&gt;loop&lt;/a&gt;.&lt;/p&gt;
</content><link xmlns:ns="http://www.w3.org/2005/Atom" ns:href="https://guide.aelve.com/haskell/static-analyzer-wishlist-lbbp2xa6#item-daxahxjp"/></entry><entry><id>zmhev6pl</id><title xmlns:ns="http://www.w3.org/2005/Atom" ns:type="text">Having outdated computations in comments</title><updated>2017-08-05T19:07:01Z</updated><content xmlns:ns="http://www.w3.org/2005/Atom" ns:type="html">&lt;h1&gt;  &lt;span class=&#34;item-name&#34;&gt;Having outdated computations in comments&lt;/span&gt;

&lt;/h1&gt;&lt;p&gt;Often people are afraid that the compiler won&#39;t simplify some arithmetic expression, and they calculate it, write the answer, and leave the expression in comments. Then someone updates the comment but forgets to recalculate the expression (or vice versa). Here the correct answer is 191, but the number written is 187:&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34;&gt;&lt;pre class=&#34;sourceCode&#34;&gt;&lt;code class=&#34;sourceCode&#34;&gt;&lt;span class=&#34;ot&#34;&gt;size ::&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;Int&lt;/span&gt;
size &lt;span class=&#34;fu&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;dv&#34;&gt;187&lt;/span&gt;       &lt;span class=&#34;co&#34;&gt;-- 4*(28+16) + 15&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
</content><link xmlns:ns="http://www.w3.org/2005/Atom" ns:href="https://guide.aelve.com/haskell/static-analyzer-wishlist-lbbp2xa6#item-zmhev6pl"/></entry><entry><id>rzwttsyt</id><title xmlns:ns="http://www.w3.org/2005/Atom" ns:type="text">Discarding data and then using it</title><updated>2017-08-05T18:59:57Z</updated><content xmlns:ns="http://www.w3.org/2005/Atom" ns:type="html">&lt;h1&gt;  &lt;span class=&#34;item-name&#34;&gt;Discarding data and then using it&lt;/span&gt;

&lt;/h1&gt;&lt;p&gt;The following code usually doesn&#39;t make sense because having a single &lt;code&gt;()&lt;/code&gt; is rarely useful:&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34;&gt;&lt;pre class=&#34;sourceCode&#34;&gt;&lt;code class=&#34;sourceCode&#34;&gt;xs &lt;span class=&#34;ot&#34;&gt;&amp;lt;-&lt;/span&gt; replicateM_ &lt;span class=&#34;fu&#34;&gt;...&lt;/span&gt;
ys &lt;span class=&#34;ot&#34;&gt;&amp;lt;-&lt;/span&gt; forM_ &lt;span class=&#34;fu&#34;&gt;...&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Having a list of &lt;code&gt;()&lt;/code&gt;s isn&#39;t useful either:&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34;&gt;&lt;pre class=&#34;sourceCode&#34;&gt;&lt;code class=&#34;sourceCode&#34;&gt;xs &lt;span class=&#34;ot&#34;&gt;&amp;lt;-&lt;/span&gt; replicateM &lt;span class=&#34;dv&#34;&gt;10&lt;/span&gt; &lt;span class=&#34;co&#34;&gt;{- something that returns () -}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
</content><link xmlns:ns="http://www.w3.org/2005/Atom" ns:href="https://guide.aelve.com/haskell/static-analyzer-wishlist-lbbp2xa6#item-rzwttsyt"/></entry><entry><id>wb8kvptq</id><title xmlns:ns="http://www.w3.org/2005/Atom" ns:type="text">Copypaste</title><updated>2017-08-05T18:42:24Z</updated><content xmlns:ns="http://www.w3.org/2005/Atom" ns:type="html">&lt;h1&gt;  &lt;span class=&#34;item-name&#34;&gt;Copypaste&lt;/span&gt;

&lt;/h1&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Using the same expression with an operator:&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34;&gt;&lt;pre class=&#34;sourceCode&#34;&gt;&lt;code class=&#34;sourceCode&#34;&gt;a &lt;span class=&#34;fu&#34;&gt;==&lt;/span&gt; a    a &lt;span class=&#34;fu&#34;&gt;/=&lt;/span&gt; a    a &lt;span class=&#34;fu&#34;&gt;+&lt;/span&gt; a    a &lt;span class=&#34;fu&#34;&gt;-&lt;/span&gt; a    a &lt;span class=&#34;fu&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; a    a &lt;span class=&#34;fu&#34;&gt;||&lt;/span&gt; a    &lt;span class=&#34;fu&#34;&gt;...&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Duplicated expressions in a list:&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34;&gt;&lt;pre class=&#34;sourceCode&#34;&gt;&lt;code class=&#34;sourceCode&#34;&gt;[a&lt;span class=&#34;fu&#34;&gt;..&lt;/span&gt;a]    [a, a&lt;span class=&#34;fu&#34;&gt;..&lt;/span&gt;]&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Duplicated branches in an &lt;code&gt;if&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34;&gt;&lt;pre class=&#34;sourceCode&#34;&gt;&lt;code class=&#34;sourceCode&#34;&gt;&lt;span class=&#34;kw&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;fu&#34;&gt;...&lt;/span&gt; &lt;span class=&#34;kw&#34;&gt;then&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;A&lt;/span&gt; &lt;span class=&#34;kw&#34;&gt;else&lt;/span&gt; &lt;span class=&#34;dt&#34;&gt;A&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Very similar but different bindings:&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34;&gt;&lt;pre class=&#34;sourceCode&#34;&gt;&lt;code class=&#34;sourceCode&#34;&gt;&lt;span class=&#34;co&#34;&gt;-- in one function&lt;/span&gt;
chainLength &lt;span class=&#34;fu&#34;&gt;=&lt;/span&gt; blockSecurityParam &lt;span class=&#34;fu&#34;&gt;*&lt;/span&gt; (length participants &lt;span class=&#34;fu&#34;&gt;-&lt;/span&gt; &lt;span class=&#34;dv&#34;&gt;1&lt;/span&gt;)

&lt;span class=&#34;co&#34;&gt;-- in another function&lt;/span&gt;
chainLength &lt;span class=&#34;fu&#34;&gt;=&lt;/span&gt; blockSecurityParam &lt;span class=&#34;fu&#34;&gt;*&lt;/span&gt; (length participants &lt;span class=&#34;fu&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;dv&#34;&gt;1&lt;/span&gt;)&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
</content><link xmlns:ns="http://www.w3.org/2005/Atom" ns:href="https://guide.aelve.com/haskell/static-analyzer-wishlist-lbbp2xa6#item-wb8kvptq"/></entry><entry><id>r4jsiyy6</id><title xmlns:ns="http://www.w3.org/2005/Atom" ns:type="text">printf arguments</title><updated>2017-08-05T17:10:26Z</updated><content xmlns:ns="http://www.w3.org/2005/Atom" ns:type="html">&lt;h1&gt;  &lt;span class=&#34;item-name&#34;&gt;printf arguments&lt;/span&gt;

&lt;/h1&gt;&lt;p&gt;It&#39;s often possible to detect in compile-time when &lt;code&gt;printf&lt;/code&gt; or &lt;code&gt;format&lt;/code&gt; (from &lt;a href=&#34;https://hackage.haskell.org/package/text-format&#34;&gt;text-format&lt;/a&gt;) is used with the wrong number of arguments:&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34;&gt;&lt;pre class=&#34;sourceCode&#34;&gt;&lt;code class=&#34;sourceCode&#34;&gt;printf &lt;span class=&#34;st&#34;&gt;&amp;quot;%s %s&amp;quot;&lt;/span&gt; a b c&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
</content><link xmlns:ns="http://www.w3.org/2005/Atom" ns:href="https://guide.aelve.com/haskell/static-analyzer-wishlist-lbbp2xa6#item-r4jsiyy6"/></entry><entry><id>xoe7jvqn</id><title xmlns:ns="http://www.w3.org/2005/Atom" ns:type="text">Weird range comparison</title><updated>2017-08-05T17:09:52Z</updated><content xmlns:ns="http://www.w3.org/2005/Atom" ns:type="html">&lt;h1&gt;  &lt;span class=&#34;item-name&#34;&gt;Weird range comparison&lt;/span&gt;

&lt;/h1&gt;&lt;p&gt;Instead of the right &lt;code&gt;3 &amp;lt; a &amp;amp;&amp;amp; a &amp;lt; 5&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34;&gt;&lt;pre class=&#34;sourceCode&#34;&gt;&lt;code class=&#34;sourceCode&#34;&gt;&lt;span class=&#34;kw&#34;&gt;if&lt;/span&gt; a &lt;span class=&#34;fu&#34;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&#34;dv&#34;&gt;3&lt;/span&gt; &lt;span class=&#34;fu&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; a &lt;span class=&#34;fu&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;dv&#34;&gt;5&lt;/span&gt;
&lt;span class=&#34;kw&#34;&gt;if&lt;/span&gt; a &lt;span class=&#34;fu&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;dv&#34;&gt;5&lt;/span&gt; &lt;span class=&#34;fu&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; a &lt;span class=&#34;fu&#34;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&#34;dv&#34;&gt;3&lt;/span&gt;
&lt;span class=&#34;fu&#34;&gt;...&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
</content><link xmlns:ns="http://www.w3.org/2005/Atom" ns:href="https://guide.aelve.com/haskell/static-analyzer-wishlist-lbbp2xa6#item-xoe7jvqn"/></entry><entry><id>n7dv2ijx</id><title xmlns:ns="http://www.w3.org/2005/Atom" ns:type="text">Dead code elimination</title><updated>2017-07-01T15:27:08Z</updated><content xmlns:ns="http://www.w3.org/2005/Atom" ns:type="html">&lt;h1&gt;  &lt;span class=&#34;item-name&#34;&gt;Dead code elimination&lt;/span&gt;

&lt;/h1&gt;&lt;p&gt;A common pattern when developing big Haskell applications is “library + executable” (with the library not being used anywhere other than the executable). Thus, it often happens that functions (and sometimes whole modules) are not used in the final executable, but GHC doesn&#39;t report them as unused because they are still exported from the library. It&#39;d be nice to be able to get a list of such functions.&lt;/p&gt;
&lt;p&gt;Note: the &lt;a href=&#34;https://github.com/ndmitchell/weeder&#34;&gt;weeder&lt;/a&gt; tool already seems to be doing it.&lt;/p&gt;
</content><link xmlns:ns="http://www.w3.org/2005/Atom" ns:href="https://guide.aelve.com/haskell/static-analyzer-wishlist-lbbp2xa6#item-n7dv2ijx"/></entry></feed>