<?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">CPP – Haskell – Aelve Guide</title><id>https://guide.aelve.com/haskell/feed/category/vww0qd72</id><updated>2017-05-13T21:26:26Z</updated><link xmlns:ns="http://www.w3.org/2005/Atom" ns:href="https://guide.aelve.com/haskell/feed/category/vww0qd72"/><entry><id>o88ct0bb</id><title xmlns:ns="http://www.w3.org/2005/Atom" ns:type="text">base-feature-macros</title><updated>2017-05-13T21:26: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;base-feature-macros&lt;/span&gt;

  
  (&lt;a href=&#34;https://hackage.haskell.org/package/base-feature-macros&#34;&gt;Hackage&lt;/a&gt;)
&lt;/h1&gt;&lt;p&gt;The &lt;a href=&#34;https://hackage.haskell.org/package/base-feature-macros&#34;&gt;base-feature-macros&lt;/a&gt; package lets you write some macros more conveniently – e.g. instead of &lt;code&gt;#if MIN_VERSION_base(4,8,0)&lt;/code&gt; you can write &lt;code&gt;#if HAVE_FOLDABLE_TRAVERSABLE_IN_PRELUDE&lt;/code&gt;, which is much more understandable to a casual reader.&lt;/p&gt;
</content><link xmlns:ns="http://www.w3.org/2005/Atom" ns:href="https://guide.aelve.com/haskell/cpp-vww0qd72#item-o88ct0bb"/></entry><entry><id>v27x182d</id><title xmlns:ns="http://www.w3.org/2005/Atom" ns:type="text">Differences between GCC and Clang</title><updated>2017-02-13T21:26:53Z</updated><content xmlns:ns="http://www.w3.org/2005/Atom" ns:type="html">&lt;h1&gt;  &lt;span class=&#34;item-name&#34;&gt;Differences between GCC and Clang&lt;/span&gt;

&lt;/h1&gt;&lt;p&gt;On Linux and Windows, GCC&#39;s CPP is used for preprocessing; on macOS – Clang&#39;s CPP. They have some differences, which you have to account for (unless you&#39;re using cpphs).&lt;/p&gt;
&lt;p&gt;If you&#39;re on Linux, use &lt;code&gt;ghc -pgmP &amp;quot;clang -E -undef -traditional&amp;quot; file.hs&lt;/code&gt; to check whether your code would compile with Clang. If you use CI (e.g. Travis-CI), you can add it to your .cabal file in the &lt;code&gt;ghc-options&lt;/code&gt; section (hidden under a flag) and run your CI builds both with and without the flag.&lt;/p&gt;
&lt;hr /&gt;
&lt;h1&gt;Single quotes&lt;/h1&gt;
&lt;p&gt;Clang is more strict about single quotes than GCC. For instance, this piece of code using &lt;code&gt;-XDataKinds&lt;/code&gt; won&#39;t be expanded correctly by Clang:&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;pp&#34;&gt;#define X(a) Foo &#39;[a]&lt;/span&gt;
X(Int)                         &amp;lt;- expanded into “Foo &#39;[a]”&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;A workaround is defining a separate macro for &lt;code&gt;&#39;&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;pp&#34;&gt;#define QUOTE &#39;&lt;/span&gt;
&lt;span class=&#34;pp&#34;&gt;#define X(a) Foo QUOTE[a]&lt;/span&gt;
X(Int)                         &amp;lt;- expanded into “Foo &#39;[Int]”&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;If you need to surround something with single quotes, this might help:&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;pp&#34;&gt;#define QUOTE() &#39;&lt;/span&gt;
&lt;span class=&#34;pp&#34;&gt;#define QLEFT(a) QUOTE()a&lt;/span&gt;
&lt;span class=&#34;pp&#34;&gt;#define Q(a) QLEFT(a)&#39;&lt;/span&gt;
Q(Int)                         &amp;lt;- expanded into “&#39;Int&#39;”&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h1&gt;Concatenation&lt;/h1&gt;
&lt;p&gt;GCC expands the following macro as &lt;code&gt;_foo&lt;/code&gt;, but Clang adds a space and produces &lt;code&gt;_ foo&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;pp&#34;&gt;#define U(x) _&lt;/span&gt;&lt;span class=&#34;co&#34;&gt;/**/&lt;/span&gt;&lt;span class=&#34;pp&#34;&gt;x&lt;/span&gt;
U(foo)&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;There is no way to get rid of the space on Clang. Either rewrite your code to not need such tricks, or use cpphs.&lt;/p&gt;
</content><link xmlns:ns="http://www.w3.org/2005/Atom" ns:href="https://guide.aelve.com/haskell/cpp-vww0qd72#item-v27x182d"/></entry><entry><id>uqlwbvrw</id><title xmlns:ns="http://www.w3.org/2005/Atom" ns:type="text">Use cpphs as the preprocessor</title><updated>2017-02-11T21:48: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;Use cpphs as the preprocessor&lt;/span&gt;

&lt;/h1&gt;&lt;p&gt;Sometimes it&#39;s easier to use &lt;a href=&#34;http://projects.haskell.org/cpphs/&#34;&gt;cpphs&lt;/a&gt; than to fight with GCC&#39;s and Clang&#39;s differences, idiosyncrasies, etc:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;[...] There have always been problems with, for instance, string gaps, and prime characters in identifiers. These problems are only going to get worse.&lt;/p&gt;
&lt;p&gt;So, it seemed right to provide an alternative to cpp, both more compatible with Haskell, and itself written in Haskell so that it can be distributed with compilers.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Cpphs handles single quotes and &lt;code&gt;/**/&lt;/code&gt; correctly, doesn&#39;t mangle Haddock comments and knows about Haskell&#39;s multiline strings.&lt;/p&gt;
&lt;p&gt;To use cpphs, you need to add these options to all sections of your .cabal file:&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34;&gt;&lt;pre class=&#34;sourceCode&#34;&gt;&lt;code class=&#34;sourceCode&#34;&gt;library
  ...
  build-tools: cpphs &amp;gt;= 1.19
  ghc-options: -pgmP cpphs -optP --cpp&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;A warning: Stack will install cpphs automatically, but cabal-install might not (and then you&#39;d have to install it manually). Thus, depending on cpphs isn&#39;t recommended for libraries that would be published on Hackage.&lt;/p&gt;
&lt;p&gt;If you can&#39;t use cpphs because of its modified LGPL license (e.g. in corporate environment where each license has to be vetted by a lawyer), you can use &lt;a href=&#34;https://github.com/acowley/hpp&#34;&gt;hpp&lt;/a&gt; instead.&lt;/p&gt;
</content><link xmlns:ns="http://www.w3.org/2005/Atom" ns:href="https://guide.aelve.com/haskell/cpp-vww0qd72#item-uqlwbvrw"/></entry><entry><id>nrzc15ch</id><title xmlns:ns="http://www.w3.org/2005/Atom" ns:type="text">Define a macro</title><updated>2017-02-09T11:30:14Z</updated><content xmlns:ns="http://www.w3.org/2005/Atom" ns:type="html">&lt;h1&gt;  &lt;span class=&#34;item-name&#34;&gt;Define a macro&lt;/span&gt;

&lt;/h1&gt;&lt;p&gt;Macros are useful when you need to write repetitive code but don&#39;t want to use Template Haskell (either because it&#39;s hard or because you want to avoid the compilation time penalty). For example,
&lt;a href=&#34;https://hackage.haskell.org/package/monad-control&#34;&gt;monad-control&lt;/a&gt; uses macros to &lt;a href=&#34;https://github.com/basvandijk/monad-control/blob/4a3ec0631dda597b1b13d1a6a756d3b651f511b4/Control/Monad/Trans/Control.hs#L332-L354&#34;&gt;generate instances&lt;/a&gt;, and
GHC uses macros to &lt;a href=&#34;https://github.com/ghc/ghc/blob/b9bebd8cedccd7e8dd6df89b5504cd8f1e7a675b/libraries/base/GHC/Float/RealFracMethods.hs#L62-L76&#34;&gt;define shorter function names&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The simplest example is defining a synonym for a function:&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;pp&#34;&gt;#define FI fromIntegral&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now &lt;code&gt;FI&lt;/code&gt; can be used anywhere instead of &lt;code&gt;fromIntegral&lt;/code&gt;. As mentioned in the introduction, it won&#39;t be expanded inside strings or words; still, it might be better to undefine it after use:&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;pp&#34;&gt;#undef FI&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;We can define a more complex macro with parameters. For instance, instead of generating lenses with &lt;code&gt;makeLenses&lt;/code&gt; we could do it with macros (sometimes it&#39;s a necessary evil, like when you want to define lenses for data families):&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;pp&#34;&gt;#define MAKE_LENS(field, lens) lens f s = (\y -&amp;gt; s {field = y}) &amp;lt;$&amp;gt; f (field s)&lt;/span&gt;

-- | Lens &lt;span class=&#34;cf&#34;&gt;for&lt;/span&gt; foo.
foo :: Lens&#39; (SomeFamily Int) Foo
MAKE_LENS(foo, _foo)&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;(Note that we can&#39;t get rid of repetition – &lt;code&gt;foo&lt;/code&gt;, &lt;code&gt;_foo&lt;/code&gt; – without breaking compatibility with Clang. If you &lt;a href=&#34;#item-uqlwbvrw&#34;&gt;use cpphs&lt;/a&gt; or don&#39;t need your code to compile on macOS, you can use &lt;code&gt;/**/&lt;/code&gt; to add the underscore instead.)&lt;/p&gt;
&lt;p&gt;Finally, you can use &lt;code&gt;\&lt;/code&gt; for longer macros:&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;pp&#34;&gt;#define BASE(M)                           \&lt;/span&gt;
&lt;span class=&#34;pp&#34;&gt;instance MonadBaseControl (M) (M) where { \&lt;/span&gt;
&lt;span class=&#34;pp&#34;&gt;    type StM (M) a = a;                   \&lt;/span&gt;
&lt;span class=&#34;pp&#34;&gt;    liftBaseWith f = f id;                \&lt;/span&gt;
&lt;span class=&#34;pp&#34;&gt;    restoreM = return;                    \&lt;/span&gt;
&lt;span class=&#34;pp&#34;&gt;    {-# INLINABLE liftBaseWith #-};       \&lt;/span&gt;
&lt;span class=&#34;pp&#34;&gt;{-# INLINABLE restoreM #-}}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This macro isn&#39;t actually multiline, though – it will be expanded into a single line (which is why curly braces were used and there&#39;s &lt;code&gt;;&lt;/code&gt; after every line).&lt;/p&gt;
</content><link xmlns:ns="http://www.w3.org/2005/Atom" ns:href="https://guide.aelve.com/haskell/cpp-vww0qd72#item-nrzc15ch"/></entry><entry><id>oh9ytz0p</id><title xmlns:ns="http://www.w3.org/2005/Atom" ns:type="text">Define a .cabal flag</title><updated>2017-02-07T18:12:40Z</updated><content xmlns:ns="http://www.w3.org/2005/Atom" ns:type="html">&lt;h1&gt;  &lt;span class=&#34;item-name&#34;&gt;Define a .cabal flag&lt;/span&gt;

&lt;/h1&gt;&lt;p&gt;Let&#39;s say you want to add asserts to your code. First, add a flag to your &lt;code&gt;.cabal&lt;/code&gt; file:&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34;&gt;&lt;pre class=&#34;sourceCode&#34;&gt;&lt;code class=&#34;sourceCode&#34;&gt;Flag asserts
  Description:   Turn on asserts
  Default:       False

library
  exposed-modules: ...

  if flag(asserts)
    cpp-options: -DASSERTS&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;(It&#39;s also possible to define a constant by writing &lt;code&gt;-DFOO=bar&lt;/code&gt;.)&lt;/p&gt;
&lt;p&gt;Now, to enable a flag during compilation, do this (to disable, use &lt;code&gt;-asserts&lt;/code&gt; instead of &lt;code&gt;asserts&lt;/code&gt;):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Cabal: &lt;code&gt;cabal configure -f asserts&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Stack: &lt;code&gt;stack build --flag pkgname:asserts&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Then you can check for this flag in code:&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;pp&#34;&gt;#ifdef ASSERTS&lt;/span&gt;
  ...
&lt;span class=&#34;pp&#34;&gt;#endif&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/cpp-vww0qd72#item-oh9ytz0p"/></entry><entry><id>v8clrp5x</id><title xmlns:ns="http://www.w3.org/2005/Atom" ns:type="text">Detect Int/Word size</title><updated>2017-02-05T15:20: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;Detect Int/Word size&lt;/span&gt;

&lt;/h1&gt;&lt;p&gt;You can use CPP to find out whether &lt;code&gt;Int&lt;/code&gt; and &lt;code&gt;Word&lt;/code&gt; have 32 bits, 64 bits, or (if you&#39;re unlucky) some other amount of bits. First you&#39;ll have to add &lt;code&gt;#include &amp;quot;MachDeps.h&amp;quot;&lt;/code&gt; to the beginning of the file. This makes the &lt;code&gt;WORD_SIZE_IN_BITS&lt;/code&gt; variable available:&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;pp&#34;&gt;#if (WORD_SIZE_IN_BITS == 64)&lt;/span&gt;
  ...
&lt;span class=&#34;pp&#34;&gt;#else&lt;/span&gt;
  ...
&lt;span class=&#34;pp&#34;&gt;#endif&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;There are &lt;a href=&#34;https://github.com/ghc/ghc/blob/master/includes/MachDeps.h&#34;&gt;other constants&lt;/a&gt; defined in MachDeps.h as well.&lt;/p&gt;
</content><link xmlns:ns="http://www.w3.org/2005/Atom" ns:href="https://guide.aelve.com/haskell/cpp-vww0qd72#item-v8clrp5x"/></entry><entry><id>flz6li4l</id><title xmlns:ns="http://www.w3.org/2005/Atom" ns:type="text">Detect architecture</title><updated>2017-02-05T15:00:07Z</updated><content xmlns:ns="http://www.w3.org/2005/Atom" ns:type="html">&lt;h1&gt;  &lt;span class=&#34;item-name&#34;&gt;Detect architecture&lt;/span&gt;

&lt;/h1&gt;&lt;p&gt;There are variables for detecting architecture:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;i386_HOST_ARCH&lt;/code&gt; – x86&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;x86_64_HOST_ARCH&lt;/code&gt; – x64&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;arm_HOST_ARCH&lt;/code&gt; – ARM (there&#39;s also &lt;code&gt;arm_HOST_ARCH_PRE_ARMv7&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;powerpc_HOST_ARCH&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;sparc_HOST_ARCH&lt;/code&gt;&lt;/li&gt;
&lt;/ul&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;pp&#34;&gt;#if defined(i386_HOST_ARCH)&lt;/span&gt;
  ...
&lt;span class=&#34;pp&#34;&gt;#elif defined(x86_64_HOST_ARCH)&lt;/span&gt;
  ...
&lt;span class=&#34;pp&#34;&gt;#else&lt;/span&gt;
&lt;span class=&#34;pp&#34;&gt;# error Unsupported architecture&lt;/span&gt;
&lt;span class=&#34;pp&#34;&gt;#endif&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;# error Unsupported architecture&lt;/code&gt; will emit an error at the CPP step (and stop compilation) if the architecture isn&#39;t one of the above.&lt;/p&gt;
</content><link xmlns:ns="http://www.w3.org/2005/Atom" ns:href="https://guide.aelve.com/haskell/cpp-vww0qd72#item-flz6li4l"/></entry><entry><id>qbrikka7</id><title xmlns:ns="http://www.w3.org/2005/Atom" ns:type="text">Detect OS</title><updated>2017-02-05T14:39:07Z</updated><content xmlns:ns="http://www.w3.org/2005/Atom" ns:type="html">&lt;h1&gt;  &lt;span class=&#34;item-name&#34;&gt;Detect OS&lt;/span&gt;

&lt;/h1&gt;&lt;p&gt;The following variables are defined depending on OS:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;mingw32_HOST_OS&lt;/code&gt; – Windows&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;darwin_HOST_OS&lt;/code&gt; – macOS&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ghcjs_HOST_OS&lt;/code&gt; – Javascript (when compiling with GHCJS)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;linux_HOST_OS&lt;/code&gt; – Linux (shouldn&#39;t be needed most of the time)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;freebsd_HOST_OS&lt;/code&gt; – FreeBSD&lt;/li&gt;
&lt;li&gt;&lt;code&gt;netbsd_HOST_OS&lt;/code&gt; – NetBSD&lt;/li&gt;
&lt;li&gt;&lt;code&gt;openbsd_HOST_OS&lt;/code&gt; – OpenBSD&lt;/li&gt;
&lt;li&gt;&lt;code&gt;solaris_HOST_OS&lt;/code&gt; – Solaris&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For instance, here&#39;s how you can detect macOS:&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;pp&#34;&gt;#ifdef darwin_HOST_OS&lt;/span&gt;
  ...
&lt;span class=&#34;pp&#34;&gt;#endif&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Note that despite lots of libraries using &lt;code&gt;#if defined(mingw32_HOST_OS) || defined(__MINGW32__)&lt;/code&gt; for detecting Windows, you don&#39;t need to do it – just &lt;code&gt;mingw32_HOST_OS&lt;/code&gt; will suffice. See this &lt;a href=&#34;https://ghc.haskell.org/trac/ghc/ticket/9945#comment:15&#34;&gt;Trac ticket&lt;/a&gt;.&lt;/p&gt;
</content><link xmlns:ns="http://www.w3.org/2005/Atom" ns:href="https://guide.aelve.com/haskell/cpp-vww0qd72#item-qbrikka7"/></entry><entry><id>c84cb8q3</id><title xmlns:ns="http://www.w3.org/2005/Atom" ns:type="text">Detect Hlint</title><updated>2017-02-05T14:31:16Z</updated><content xmlns:ns="http://www.w3.org/2005/Atom" ns:type="html">&lt;h1&gt;  &lt;span class=&#34;item-name&#34;&gt;Detect Hlint&lt;/span&gt;

&lt;/h1&gt;&lt;p&gt;Sometimes you want to hide some code from &lt;a href=&#34;https://github.com/ndmitchell/hlint&#34;&gt;Hlint&lt;/a&gt; (for instance, if Hlint&#39;s parser doesn&#39;t support a particular language feature yet).&lt;/p&gt;
&lt;p&gt;You can do it by defining &lt;code&gt;HLINT&lt;/code&gt; (e.g. by writing a script like &lt;a href=&#34;https://github.com/ekmett/lens/blob/6f8e5539fccca2e07a3e0b54bb0ec3364f9f3d52/tests/hlint.hs&#34;&gt;lens&lt;/a&gt; does, or just by passing &lt;code&gt;--cpp-define=HLINT&lt;/code&gt; to Hlint) and then wrapping code into an &lt;code&gt;#ifndef HLINT&lt;/code&gt; section:&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;pp&#34;&gt;#ifndef HLINT&lt;/span&gt;
  ...
&lt;span class=&#34;pp&#34;&gt;#endif&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/cpp-vww0qd72#item-c84cb8q3"/></entry><entry><id>qxhl6vk6</id><title xmlns:ns="http://www.w3.org/2005/Atom" ns:type="text">Check version of a library</title><updated>2017-02-05T14:16: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;Check version of a library&lt;/span&gt;

&lt;/h1&gt;&lt;p&gt;Cabal automatically generates  macros (&lt;code&gt;MIN_VERSION_&amp;lt;library&amp;gt;&lt;/code&gt;) for all libraries your project depends upon. E.g. you can do something if e.g. &lt;code&gt;bytestring&lt;/code&gt; is 0.10.4 or newer:&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;pp&#34;&gt;#if MIN_VERSION_bytestring(0,10,4)&lt;/span&gt;
  ...
&lt;span class=&#34;pp&#34;&gt;#endif&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;If a library has hyphens &lt;code&gt;-&lt;/code&gt; in its name, replace them with underscores &lt;code&gt;_&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;pp&#34;&gt;#if MIN_VERSION_template_haskell(2,11,0)&lt;/span&gt;
  ...
&lt;span class=&#34;pp&#34;&gt;#endif&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/cpp-vww0qd72#item-qxhl6vk6"/></entry><entry><id>fkuvztqe</id><title xmlns:ns="http://www.w3.org/2005/Atom" ns:type="text">Check GHC version</title><updated>2017-02-04T14:35:56Z</updated><content xmlns:ns="http://www.w3.org/2005/Atom" ns:type="html">&lt;h1&gt;  &lt;span class=&#34;item-name&#34;&gt;Check GHC version&lt;/span&gt;

&lt;/h1&gt;&lt;p&gt;&lt;em&gt;GHC versions currently in use: 7.8 = &lt;code&gt;708&lt;/code&gt;, 7.10 = &lt;code&gt;710&lt;/code&gt;, 8.0 = &lt;code&gt;800&lt;/code&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Do something if GHC is older than 7.10:&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;pp&#34;&gt;#if __GLASGOW_HASKELL__ &amp;lt; 710&lt;/span&gt;
  ...
&lt;span class=&#34;pp&#34;&gt;#endif&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Use different code for GHC 8.0 and older versions:&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;pp&#34;&gt;#if __GLASGOW_HASKELL__ &amp;gt;= 800&lt;/span&gt;
  ...
&lt;span class=&#34;pp&#34;&gt;#else&lt;/span&gt;
  ...
&lt;span class=&#34;pp&#34;&gt;#endif&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;If you need to check for patch level as well (e.g. detect GHC 8.0.1 but not 8.0.2), you can use a .cabal flag:&lt;/p&gt;
&lt;div class=&#34;sourceCode&#34;&gt;&lt;pre class=&#34;sourceCode&#34;&gt;&lt;code class=&#34;sourceCode&#34;&gt;library
  ...
  if impl(ghc == 8.0.1)
    cpp-options: -DGHC_801&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;For more info on .cabal flags, see &lt;a href=&#34;#item-oh9ytz0p&#34;&gt;Define a .cabal flag&lt;/a&gt;.&lt;/p&gt;
</content><link xmlns:ns="http://www.w3.org/2005/Atom" ns:href="https://guide.aelve.com/haskell/cpp-vww0qd72#item-fkuvztqe"/></entry></feed>