<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>haskell &amp;mdash; Jerry of the Week</title>
    <link>https://write.in0rdr.ch/tag:haskell</link>
    <description>ˈdʒɛri - Individual who sends life against the grain no matter the consequences</description>
    <pubDate>Thu, 23 Apr 2026 23:31:56 +0000</pubDate>
    <item>
      <title>Building Haskell projects for Nix</title>
      <link>https://write.in0rdr.ch/building-haskell-projects-for-nix</link>
      <description>&lt;![CDATA[Similar to the last post on building a C project, today I quickly cover how to build a Haskell project.&#xA;&#xA;You might ask why? I got asked about that stuff by my friendly office colleague Samuel. By the way, without him I would have never installed/used Nixos in the first place. Good fella, go checkout his blog.&#xA;&#xA;#packaging #coding #nix #haskell&#xA;!--more--&#xA;&#xA;The goal was to package oama. Oama helps you to renew OAuth2 tokens from the command line. To be honest, I haven&#39;t checked the details on how it works yet, I was only interested in packaging it for Nix.&#xA;&#xA;I was reading a bit on how it can be used with my favorite msmtp client.&#xA;&#xA;Then I read some of the Nix documentation on how to build and use Haskell packages. They describe how to quickly bootstrap development environments (i.e., a Nix shell) using the handy cabal2nix utility.&#xA;&#xA;The first step for packaging was also to convert the cabal description of the package into a valid Nix expression which already proved useful for development purposes.&#xA;&#xA;git clone https://github.com/pdobsan/oama.git oama.git&#xA;cd oama.git&#xA;cabal2nix .   oama.nix&#xA;&#xA;Create default.nix:&#xA;Retrieve nixpkgs impurely from NIXPATH for now, you can pin it instead, of course.&#xA;{ pkgs ? import nixpkgs {} }:&#xA;&#xA;use the nixpkgs default haskell package set&#xA;pkgs.haskellPackages.callPackage ./oama.nix { }&#xA;&#xA;If you have a look at oama.nix it contains a lot of references to Haskell packages (.e.g, haskellPackages.aeson). The callPackage takes care of the name resolution in this case. haskellPackages.mkDerivation is a wrapper around stdenv.mkDerivation (see last post building a C project), but works without the standard Haskell build tool cabal-install.&#xA;&#xA;To build oama and quickly run it in a shell:&#xA;nix-shell -p cabal-install&#xA;nix-build default.nix&#xA;./result/bin/oama&#xA;&#xA;I did not look further into shellFor at this point, because I was interested in creating a Nix package that I can install globally.&#xA;&#xA;For this, I took the &#34;stdenv template&#34; from the last post) and merged 😻 it with the oama.nix output from cabal2nix. The result:&#xA;&#xA;let&#xA;  pkgs = import nixpkgs { };&#xA;  hpkgs = pkgs.haskellPackages;&#xA;in&#xA;  hpkgs.mkDerivation {&#xA;    pname = &#34;oama&#34;;&#xA;    version = &#34;0.10.1&#34;;&#xA;    src = pkgs.fetchgit {&#xA;      url = &#34;https://github.com/pdobsan/oama.git&#34;;&#xA;      rev = &#34;refs/tags/0.10.1&#34;;&#xA;      hash = &#34;sha256-mQBlCrF9rvFOfSOxhMi6JUKDJocFmO4Hhc3Zy7AqiXk=&#34;;&#xA;    };&#xA;&#xA;    isLibrary = true;&#xA;    isExecutable = true;&#xA;    libraryHaskellDepends = with hpkgs; [&#xA;      aeson base bytestring containers directory hsyslog http-conduit&#xA;      network-uri optparse-applicative pretty-simple process string-qq&#xA;      strings text time twain unix utf8-string warp yaml&#xA;    ];&#xA;    executableHaskellDepends = with hpkgs; [&#xA;      aeson base bytestring containers directory hsyslog http-conduit&#xA;      network-uri optparse-applicative pretty-simple process string-qq&#xA;      strings text time twain unix utf8-string warp yaml&#xA;    ];&#xA;&#xA;    mainProgram = &#34;oama&#34;;&#xA;    license = pkgs.lib.licenses.bsd3;&#xA;  }&#xA;&#xA;Essentially, I only had to use nix-prefetch-git to get the shasum of the git revision and make sure I use the pkgs and hpkgs (reference to pkgs.haskellPackages) correctly in the right places.&#xA;&#xA;Afterwards, again, building and installing oama globally was a peace of cake 🧁:&#xA;&#xA;nix-build oama.nix&#xA;nix-env -i -f oama.nix&#xA;&#xA;Now I only have to figure out what to do with this tool 🤔 but this is left for another post.&#xA;&#xA;div style=&#34;text-align:center; font-size: 0.8em&#34;&#xD;&#xA;a href=&#34;https://write.in0rdr.ch/feed&#34;&amp;#128732; RSS/a | a href=&#34;https://m.in0rdr.ch/in0rdr&#34;&amp;#128024; Fediverse/a | a href=&#34;https://chat.in0rdr.ch/#/guest?join=p0c@conference.in0rdr.ch&#34;&amp;#128172; XMPP/a&#xD;&#xA;/div]]&gt;</description>
      <content:encoded><![CDATA[<p>Similar to the last post on <a href="https://write.in0rdr.ch/building-and-installing-a-c-project-with-nix">building a C project</a>, today I quickly cover how to build a Haskell project.</p>

<p>You might ask why? I got asked about that stuff by my friendly office colleague Samuel. By the way, without him I would have never installed/used Nixos in the first place. Good fella, go checkout his <a href="https://blog.yosemitesam.ch">blog</a>.</p>

<p><a href="https://write.in0rdr.ch/tag:packaging" class="hashtag"><span>#</span><span class="p-category">packaging</span></a> <a href="https://write.in0rdr.ch/tag:coding" class="hashtag"><span>#</span><span class="p-category">coding</span></a> <a href="https://write.in0rdr.ch/tag:nix" class="hashtag"><span>#</span><span class="p-category">nix</span></a> <a href="https://write.in0rdr.ch/tag:haskell" class="hashtag"><span>#</span><span class="p-category">haskell</span></a>
</p>

<p>The goal was to package <a href="https://github.com/pdobsan/oama"><code>oama</code></a>. Oama helps you to renew OAuth2 tokens from the command line. To be honest, I haven&#39;t checked the details on how it works yet, I was only interested in packaging it for Nix.</p>

<p>I was reading a bit on <a href="https://wiki.archlinux.org/title/msmtp#OAuth2_Setup">how it can be used with my favorite <code>msmtp</code> client</a>.</p>

<p>Then I read some of the <a href="https://nixos.org/manual/nixpkgs/stable/#haskell">Nix documentation on how to build and use Haskell packages</a>. They describe how to quickly bootstrap development environments (i.e., a Nix shell) using the handy <a href="https://hackage.haskell.org/package/cabal2nix#readme"><code>cabal2nix</code> utility</a>.</p>

<p>The first step for packaging was also to convert the <code>cabal</code> description of the package into a valid Nix expression which already proved useful for development purposes.</p>

<pre><code class="language-bash">git clone https://github.com/pdobsan/oama.git oama.git
cd oama.git
cabal2nix . &gt; oama.nix
</code></pre>

<p>Create <code>default.nix</code>:</p>

<pre><code># Retrieve nixpkgs impurely from NIX_PATH for now, you can pin it instead, of course.
{ pkgs ? import &lt;nixpkgs&gt; {} }:

# use the nixpkgs default haskell package set
pkgs.haskellPackages.callPackage ./oama.nix { }
</code></pre>

<p>If you have a look at <code>oama.nix</code> it contains a lot of references to Haskell packages (.e.g, <a href="https://search.nixos.org/packages?channel=23.11&amp;show=haskellPackages.aeson"><code>haskellPackages.aeson</code></a>). The <code>callPackage</code> takes care of the name resolution in this case. <code>haskellPackages.mkDerivation</code> is a wrapper around <code>stdenv.mkDerivation</code> (see last post <a href="https://write.in0rdr.ch/building-and-installing-a-c-project-with-nix">building a C project</a>), but works without the standard Haskell build tool <code>cabal-install</code>.</p>

<p>To build <code>oama</code> and quickly run it in a shell:</p>

<pre><code class="language-bash">nix-shell -p cabal-install
nix-build default.nix
./result/bin/oama
</code></pre>

<p>I did not look further into <code>shellFor</code> at this point, because I was interested in creating a Nix package that I can install globally.</p>

<p>For this, I took the “stdenv template” from the last post and merged 😻 it with the <code>oama.nix</code> output from <code>cabal2nix</code>. The result:</p>

<pre><code class="language-nix">let
  pkgs = import &lt;nixpkgs&gt; { };
  hpkgs = pkgs.haskellPackages;
in
  hpkgs.mkDerivation {
    pname = &#34;oama&#34;;
    version = &#34;0.10.1&#34;;
    src = pkgs.fetchgit {
      url = &#34;https://github.com/pdobsan/oama.git&#34;;
      rev = &#34;refs/tags/0.10.1&#34;;
      hash = &#34;sha256-mQBlCrF9rvFOfSOxhMi6JUKDJocFmO4Hhc3Zy7AqiXk=&#34;;
    };

    isLibrary = true;
    isExecutable = true;
    libraryHaskellDepends = with hpkgs; [
      aeson base bytestring containers directory hsyslog http-conduit
      network-uri optparse-applicative pretty-simple process string-qq
      strings text time twain unix utf8-string warp yaml
    ];
    executableHaskellDepends = with hpkgs; [
      aeson base bytestring containers directory hsyslog http-conduit
      network-uri optparse-applicative pretty-simple process string-qq
      strings text time twain unix utf8-string warp yaml
    ];

    mainProgram = &#34;oama&#34;;
    license = pkgs.lib.licenses.bsd3;
  }
</code></pre>

<p>Essentially, I only had to use <code>nix-prefetch-git</code> to get the shasum of the git revision and make sure I use the <code>pkgs</code> and <code>hpkgs</code> (reference to <code>pkgs.haskellPackages</code>) correctly in the right places.</p>

<p>Afterwards, again, building and installing <code>oama</code> globally was a peace of cake 🧁:</p>

<pre><code class="language-bash">nix-build oama.nix
nix-env -i -f oama.nix
</code></pre>

<p>Now I only have to figure out what to do with this tool 🤔 but this is left for another post.</p>

<div style="text-align:center; font-size: 0.8em">
<a href="https://write.in0rdr.ch/feed">🛜 RSS</a> | <a href="https://m.in0rdr.ch/in0rdr">🐘 Fediverse</a> | <a href="https://chat.in0rdr.ch/#/guest?join=p0c@conference.in0rdr.ch">💬 XMPP</a>
</div>
]]></content:encoded>
      <guid>https://write.in0rdr.ch/building-haskell-projects-for-nix</guid>
      <pubDate>Fri, 17 May 2024 17:50:48 +0000</pubDate>
    </item>
  </channel>
</rss>