<p>With small programs it’s easy enough to have all code in single file. But as the program grows, you eventually want to organize things into separate files. In this episode I’ll talk a bit how to define modules and how to use them.</p>
<h2 id="defining">Defining</h2>
<p>Each module is defined in separate file. In our example, we have file called <code>multiplexer.hs</code>, which contains our module definition.</p>
<p>At the beginning of the file, we have following:</p>
<pre><code>module Multiplexer (mix, match, Plexer, Scooper(..))
  where
  ....</code></pre>
<p>We’re omitting actual function and type definitions as they aren’t important to this episode. In any case, there’s two functions: <code>mix</code> and <code>match</code> and two types: <code>Plexer</code> and <code>Scooper</code> that module exports (that is, these are available outside of the module). <code>Plexer</code> is imported as a type only and <code>Scooper</code> with field accessors or value constructors depending if it’s a record or algebraic datatype.</p>
<h2 id="using-modules">Using modules</h2>
<p>In order to be able to use identifiers defined in separate module, we have to import them into our current one. In our imaginary program, we have <code>main.hs</code> that defines entry point for our program and we would like to import the definitions from <code>Multiplexer</code> module.</p>
<p>Easiest one is to just have <code>import Multiplexer</code> at the start of the <code>main</code>. This brings all exported identifiers from <code>Multiplexer</code> and we can then use them. Both qualified and unqualified names are imported. Qualified means name is prepended with module name: <code>Multiplexer.mix</code> instead of just <code>mix</code>.</p>
<p>If we want, we can specify what exactly should be imported: <code>import Multiplexer (mix, match)</code>. This causes only functions <code>mix</code> and <code>match</code> be imported, while <code>Plexer</code> and <code>Scooper</code> are unavailable for us. Again, both qualified and unqualified names are imported.</p>
<p>In case we want only qualified names, we’ll write <code>import qualified Multiplexer</code>. After this <code>mix</code> isn’t available, but <code>Multiplexer.mix</code> is (and all the other identifiers exported by <code>Multiplexer</code>).</p>
<p>Sometimes module name is long and tedious to repeat when using qualified names. In these cases, renaming module while importing is a good option. This can be done by writing <code>import Multiplexer as M</code>. After this, instead of <code>Multiplexer.mix</code> you write <code>M.mix</code>.</p>
<p>Final thing I’m going to mention is importing everything else except specified identifiers. This is done by writing <code>import Multiplexer hiding (mix)</code>. This imports everything exported by <code>Multiplexer</code>, except <code>mix</code>.</p>
<h2 id="summary">Summary</h2>
<p>There are many ways of importing and they can be mixed. Here’s a list of them:</p>
<ul>
<li><code>import Multiplexer</code></li>
<li><code>import Multiplexer ()</code></li>
<li><code>import Multiplexer (mix, match, Plexer, Scooper(..))</code></li>
<li><code>import qualified Multiplexer</code></li>
<li><code>import qualified Multiplexer (mix, match, Plexer, Scooper(..))</code></li>
<li><code>import Multiplexer hiding (mix, match)</code></li>
<li><code>import qualified Multiplexer hiding (Plexer, Scooper)</code></li>
<li><code>import Multiplexer as M</code></li>
<li><code>import Multiplexer as M (mix, match)</code></li>
<li><code>import qualified Multiplexer as M</code></li>
<li><code>import qualified Multiplexer as M (Plexer, Scooper(..))</code></li>
</ul>
<p>In short:</p>
<ul>
<li>Some identifiers can be chosen to be imported, while leaving others unimported</li>
<li>Modules can be imported qualified (forcing an obligatory namespace qualifier to imported identifiers).</li>
<li>Some identifiers can be skipped via the hiding clause.</li>
<li>The module namespace can be renamed, with an as clause.</li>
</ul>
<h2 id="prelude">Prelude</h2>
<p>Prelude is base module containing lots of helpful types and functions, which is automatically imported by every module. If this is not what you want, there’s two options. First one is to use pragma at start of the file: <code>{-# LANGUAGE NoImplicitPrelude #-}</code>, which causes <code>Prelude</code> not to be imported. Another one is to manually import <code>Prelude</code>, which turns of automatic import: <code>import qualified Prelude as P</code>.</p>
<h2 id="closing">Closing</h2>
<p>When system grows, it’s helpful to break it into more manageable pieces. For this we use modules. <code>import</code> is used to bring identifiers from other modules into current one.</p>
<p>Questions, comments and feedback is welcomed. Best way to reach me is either email or in fediverse where I’m <code>Tuula@mastodon.social</code></p>
