<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Parambir Singh</title>
    <description>The latest articles on DEV Community by Parambir Singh (@parambirs).</description>
    <link>https://dev.to/parambirs</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F107560%2F6cb2c7ea-8cb2-42a3-92fa-25ca88042adc.jpg</url>
      <title>DEV Community: Parambir Singh</title>
      <link>https://dev.to/parambirs</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/parambirs"/>
    <language>en</language>
    <item>
      <title>When ChatGPT is better than Google</title>
      <dc:creator>Parambir Singh</dc:creator>
      <pubDate>Tue, 26 Mar 2024 17:17:44 +0000</pubDate>
      <link>https://dev.to/parambirs/when-chatgpt-is-better-than-google-5cjl</link>
      <guid>https://dev.to/parambirs/when-chatgpt-is-better-than-google-5cjl</guid>
      <description>&lt;p&gt;I am not sure how helpful ChatGPT will be for writing real world code. But it can be a great improvement over Google when you are looking for a quick answer about things like regular expressions or Unix commands. Recently, I had to write a cron expression for a task that repeats regularly, and I found that using ChatGPT was more convenient than Google.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--MHroyAsq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://parambirs.github.io/images/2023/cron-chatgpt.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--MHroyAsq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://parambirs.github.io/images/2023/cron-chatgpt.jpg" alt="ChatGPT" width="800" height="274"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>search</category>
      <category>chatgpt</category>
      <category>google</category>
      <category>cron</category>
    </item>
    <item>
      <title>scalac -feature</title>
      <dc:creator>Parambir Singh</dc:creator>
      <pubDate>Sat, 27 Jun 2020 19:13:34 +0000</pubDate>
      <link>https://dev.to/parambirs/scalac-feature-38il</link>
      <guid>https://dev.to/parambirs/scalac-feature-38il</guid>
      <description>&lt;p&gt;A useful option to turn on for the scala compiler is &lt;code&gt;-feature&lt;/code&gt;. It emits warning and location for usages of features that should be imported explicitly.&lt;/p&gt;

&lt;p&gt;An example such an advanced feature is implicit conversions. An implicit conversion is an implicit value of type &lt;code&gt;A =&amp;gt; B&lt;/code&gt;. e.g.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scala"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Array&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="o"&gt;])&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Unit&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;val&lt;/span&gt; &lt;span class="nv"&gt;s&lt;/span&gt; &lt;span class="k"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Hello, world!"&lt;/span&gt;
    &lt;span class="k"&gt;val&lt;/span&gt; &lt;span class="nv"&gt;len&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Int&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;
    &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;len&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;implicit&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;stringToInt&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Int&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;s&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;length&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Compiling this piece of code with the &lt;code&gt;-feature&lt;/code&gt; scalac flag enabled gives the following warning:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[warn] Main.scala:8:16: implicit conversion method stringToInt should be enabled
[warn] by making the implicit value scala.language.implicitConversions visible.
[warn] ----
[warn] This can be achieved by adding the import clause 'import scala.language.implicitConversions'
[warn] or by setting the compiler option -language:implicitConversions.
[warn] See the Scaladoc for value scala.language.implicitConversions for a discussion
[warn] why the feature should be explicitly enabled.
[warn]   implicit def stringToInt(s: String): Int = s.length
[warn]                ^
[warn] one warning found
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>scala</category>
      <category>scalac</category>
    </item>
    <item>
      <title>Easily distributable Scala CLIs using jlink</title>
      <dc:creator>Parambir Singh</dc:creator>
      <pubDate>Thu, 26 Mar 2020 01:06:13 +0000</pubDate>
      <link>https://dev.to/parambirs/easily-distributable-scala-clis-using-jlink-18fe</link>
      <guid>https://dev.to/parambirs/easily-distributable-scala-clis-using-jlink-18fe</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Final code for this project is available at &lt;a href="https://github.com/parambirs/simple-scala-cli"&gt;github.com/parambirs/simple-scala-cli&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;JDK 9 added the &lt;a href="https://docs.oracle.com/javase/9/tools/jlink.htm"&gt;jlink&lt;/a&gt; tool that allows us to create a distributable custom JRE that containing only specific JDK modules our application needs. We no longer need to expect customers to have Java pre-installed or bundle the complete JRE (a few hundred MBs) with our app. I've created a few example apps where the uncompressed runtime is between 40MB to 90MB depending upon external libraries used by the app. After zipping, the package is around 20-25 MB. For me, this makes JVM a great platform for writing and distributing command-line apps comparable to Python or Ruby.&lt;/p&gt;

&lt;p&gt;In this post, we'll see how to create a simple "hello world" CLI written in Scala (although it's possible to write apps using any JVM language). This app will make an HTTP call using Java's new &lt;code&gt;java.net.http&lt;/code&gt; module. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note: You'll need JDK 9 or later to follow along this tutorial.&lt;/strong&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Create a new sbt project
&lt;/h1&gt;

&lt;p&gt;I created a new sbt project using IntelliJ:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fcdve2jtgvs6rejacf3cy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fcdve2jtgvs6rejacf3cy.png" alt="New IntelliJ SBT Project" width="800" height="308"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Add &lt;code&gt;src/main/scala/App.scala&lt;/code&gt; file that prints a message to the terminal when run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scala"&gt;&lt;code&gt;&lt;span class="k"&gt;object&lt;/span&gt; &lt;span class="nc"&gt;App&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Array&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="o"&gt;])&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Unit&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Hello, from scala command-line app"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's test that our basic app works from the command line by running it via sbt:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;~/t/simple-scala-cli&amp;gt; sbt run
......
[info] running App 
Hello, from scala command-line app
[success] Total time: 4 s
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Add sbt-native-packager plugin
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://www.scala-sbt.org/sbt-native-packager/index.html"&gt;sbt-native-packager&lt;/a&gt; is an sbt plugin that makes it easy to build packages for different operating systems. We'll use its &lt;a href="https://www.scala-sbt.org/sbt-native-packager/archetypes/jlink_plugin.html"&gt;Jlink plugin&lt;/a&gt; to generate a custom JRE for our application.&lt;/p&gt;

&lt;p&gt;Add or edit the &lt;code&gt;project/plugins.sbt&lt;/code&gt; file to add the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scala"&gt;&lt;code&gt;&lt;span class="nf"&gt;addSbtPlugin&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"com.typesafe.sbt"&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="s"&gt;"sbt-native-packager"&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="s"&gt;"1.7.0"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We need to enable the &lt;code&gt;JlinkPlugin&lt;/code&gt; in &lt;code&gt;build.sbt&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;enablePlugins(JlinkPlugin)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, we can create a custom distribution via the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;~/t/simple-scala-cli&amp;gt; sbt stage
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Our CLI app with a custom JRE is available in &lt;code&gt;target/universal/stage&lt;/code&gt; directory:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Frg4a4cecwrdqkwgepbzb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Frg4a4cecwrdqkwgepbzb.png" alt="Custom JRE" width="800" height="186"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let's run our app from the &lt;code&gt;stage&lt;/code&gt; directory:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;~/t/simple-scala-cli&amp;gt; ./target/universal/stage/bin/simple-scala-cli 
Hello, from scala command-line app
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Great! It works. But how can we be sure that it's not using the system wide Java installation on my machine? We can rename the &lt;code&gt;stage/jre&lt;/code&gt; directory to something else and try again:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; ~/t/simple-scala-cli&amp;gt; mv ./target/universal/stage/jre ./target/universal/stage/xyz

~/t/simple-scala-cli&amp;gt; ./target/universal/stage/bin/simple-scala-cli
No java installations was detected.
Please go to http://www.java.com/getjava/ and download


~/t/simple-scala-cli&amp;gt; mv ./target/universal/stage/xyz ./target/universal/stage/jre

~/t/simple-scala-cli&amp;gt; ./target/universal/stage/bin/simple-scala-cli
Hello, from scala command-line app
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Cool! It is indeed using the custom JRE image. On my machine the size of the stage directory is 46.9 MB. After zipping it up, the size gets reduced to 19.3 MB.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Let me reiterate - This 20MB zip file contains everything that your clients need to run your app. JVM apps aren't that verbose anymore compared to standalone ruby/python apps that bundle their runtime!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  What does jlink plugin do?
&lt;/h1&gt;

&lt;p&gt;The Jlink plugin performs two important steps in the build process. Here're the two relevant lines from the &lt;code&gt;sbt stage&lt;/code&gt; command output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[info] Running: jdeps --multi-release 13 -R /Users/parambirs/tmp/simple-scala-cli/target/scala-2.13/classes /Users/parambirs/Library/Caches/Coursier/v1/https/repo1.maven.org/maven2/org/scala-lang/scala-library/2.13.1/scala-library-2.13.1.jar
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It first runs &lt;code&gt;jdeps&lt;/code&gt; to determine which java modules are being used by our codebase.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[info] Running: jlink --output /Users/parambirs/tmp/simple-scala-cli/target/jlink/output --add-modules java.base
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It then runs &lt;code&gt;jlink&lt;/code&gt; to build a custom JRE that includes all the Java modules our app will need. In this simple application, we are only using the &lt;code&gt;java.base&lt;/code&gt; module.&lt;/p&gt;

&lt;h1&gt;
  
  
  Making an HTTP call
&lt;/h1&gt;

&lt;p&gt;Let's make our app do something more than just printing hello. We'll make the app fetch and print &lt;a href="//google.ca"&gt;google.ca&lt;/a&gt; home page HTML to the console. I'm not using any 3rd party HTTP client as &lt;a href="https://www.baeldung.com/java-9-http-client"&gt;Java now comes with a built-in easy-to-use one&lt;/a&gt;. Here's the Main class after the modifications:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scala"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.net.URI&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.net.http.HttpResponse.BodyHandlers&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.net.http.&lt;/span&gt;&lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="nc"&gt;HttpClient&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;HttpRequest&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;object&lt;/span&gt; &lt;span class="nc"&gt;App&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Array&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="o"&gt;])&lt;/span&gt;&lt;span class="k"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Unit&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;val&lt;/span&gt; &lt;span class="nv"&gt;uri&lt;/span&gt; &lt;span class="k"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;URI&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"https://google.ca"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;val&lt;/span&gt; &lt;span class="nv"&gt;client&lt;/span&gt; &lt;span class="k"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;HttpClient&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;newHttpClient&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;val&lt;/span&gt; &lt;span class="nv"&gt;request&lt;/span&gt; &lt;span class="k"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;HttpRequest&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;newBuilder&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;uri&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="py"&gt;build&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;val&lt;/span&gt; &lt;span class="nv"&gt;response&lt;/span&gt; &lt;span class="k"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;send&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;BodyHandlers&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;ofString&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt;
    &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;Console&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;YELLOW&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nv"&gt;response&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;body&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nv"&gt;Console&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="py"&gt;RESET&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's test our App :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sbt:simple-scala-cli&amp;gt; run
[info] Compiling 1 Scala source to /Users/parambirs/tmp/simple-scala-cli/target/scala-2.13/classes ...
[info] running App 
&amp;lt;HTML&amp;gt;&amp;lt;HEAD&amp;gt;&amp;lt;meta http-equiv="content-type" content="text/html;charset=utf-8"&amp;gt;
&amp;lt;TITLE&amp;gt;301 Moved&amp;lt;/TITLE&amp;gt;&amp;lt;/HEAD&amp;gt;&amp;lt;BODY&amp;gt;
&amp;lt;H1&amp;gt;301 Moved&amp;lt;/H1&amp;gt;
The document has moved
&amp;lt;A HREF="https://www.google.ca/"&amp;gt;here&amp;lt;/A&amp;gt;.
&amp;lt;/BODY&amp;gt;&amp;lt;/HTML&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Okay, looks good to ship. Let's package it up:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sbt:simple-scala-cli&amp;gt; stage
...
[info] Running: jdeps --multi-release 13 -R /Users/parambirs/tmp/simple-scala-cli/target/scala-2.13/classes /Users/parambirs/Library/Caches/Coursier/v1/https/repo1.maven.org/maven2/org/scala-lang/scala-library/2.13.1/scala-library-2.13.1.jar
...
[info] Running: jlink --output /Users/parambirs/tmp/simple-scala-cli/target/jlink/output --add-modules java.base,java.net.http
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see here, &lt;code&gt;jdeps&lt;/code&gt; identified that we need both &lt;code&gt;java.base&lt;/code&gt; and &lt;code&gt;java.net.http&lt;/code&gt; modules at runtime and &lt;code&gt;jlink&lt;/code&gt; added them to our runtime image.&lt;/p&gt;

&lt;h1&gt;
  
  
  Wrapping up
&lt;/h1&gt;

&lt;p&gt;Seems like we're ready to ship our CLI to our clients. However, before we can do that, we need to make sure it works:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;~/t/simple-scala-cli&amp;gt; ./target/universal/stage/bin/simple-scala-cli
Exception in thread "main" javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
    at java.net.http/jdk.internal.net.http.HttpClientImpl.send(HttpClientImpl.java:568)
    at java.net.http/jdk.internal.net.http.HttpClientFacade.send(HttpClientFacade.java:119)
    at App$.main(App.scala:11)
    at App.main(App.scala)
Caused by: javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
    at java.base/sun.security.ssl.Alert.createSSLException(Alert.java:131)
    at java.base/sun.security.ssl.Alert.createSSLException(Alert.java:117)
    at .......
        ......
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Oops! Looks like we are missing something in our runtime JRE. I had to spend some time googling to fix this. We need &lt;code&gt;jdk.crypto.ec&lt;/code&gt; module for SSL to work correctly, however, &lt;code&gt;jdeps&lt;/code&gt; isn't able to figure this out. The solution is to add this jlink dependency in our &lt;code&gt;build.sbt&lt;/code&gt; file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;jlinkModules += "jdk.crypto.ec"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's build and test our runtime image one more time:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;~/t/simple-scala-cli [1]&amp;gt; sbt stage
...
[info] Running: jdeps --multi-release 13 -R /Users/parambirs/tmp/simple-scala-cli/target/scala-2.13/classes /Users/parambirs/Library/Caches/Coursier/v1/https/repo1.maven.org/maven2/org/scala-lang/scala-library/2.13.1/scala-library-2.13.1.jar
[info] Running: jlink --output /Users/parambirs/tmp/simple-scala-cli/target/jlink/output --add-modules java.base,java.net.http,jdk.crypto.ec
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;~/t/simple-scala-cli&amp;gt; ./target/universal/stage/bin/simple-scala-cli
&amp;lt;HTML&amp;gt;&amp;lt;HEAD&amp;gt;&amp;lt;meta http-equiv="content-type" content="text/html;charset=utf-8"&amp;gt;
&amp;lt;TITLE&amp;gt;301 Moved&amp;lt;/TITLE&amp;gt;&amp;lt;/HEAD&amp;gt;&amp;lt;BODY&amp;gt;
&amp;lt;H1&amp;gt;301 Moved&amp;lt;/H1&amp;gt;
The document has moved
&amp;lt;A HREF="https://www.google.ca/"&amp;gt;here&amp;lt;/A&amp;gt;.
&amp;lt;/BODY&amp;gt;&amp;lt;/HTML&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Great! Finally we have a working and distributable command line app. After adding two extra modules, the runtime image size became 48.8MB uncompressed and 19.9MB when zipped.&lt;/p&gt;

&lt;p&gt;Hope you found this useful.&lt;/p&gt;

</description>
      <category>scala</category>
      <category>jlink</category>
      <category>cli</category>
      <category>jvm</category>
    </item>
    <item>
      <title>TIL: Calculating n digits of pi using Chudnovsky Algorithm</title>
      <dc:creator>Parambir Singh</dc:creator>
      <pubDate>Sat, 10 Aug 2019 19:26:25 +0000</pubDate>
      <link>https://dev.to/parambirs/til-calculating-n-digits-of-pi-using-chudnovsky-algorithm-1j10</link>
      <guid>https://dev.to/parambirs/til-calculating-n-digits-of-pi-using-chudnovsky-algorithm-1j10</guid>
      <description>&lt;p&gt;Today I stumbled upon &lt;a href="https://en.wikipedia.org/wiki/Chudnovsky_algorithm"&gt;Chudnovsky Algorithm&lt;/a&gt; to calculate the value of π to N digits of precision. Python code for this algorithm looks like the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;decimal&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;compute_pi&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;decimal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getcontext&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="n"&gt;prec&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
    &lt;span class="n"&gt;C&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;426880&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;decimal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Decimal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10005&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;sqrt&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;K&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;6.&lt;/span&gt;
    &lt;span class="n"&gt;M&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;1.&lt;/span&gt;
    &lt;span class="n"&gt;X&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
    &lt;span class="n"&gt;L&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;13591409&lt;/span&gt;
    &lt;span class="n"&gt;S&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;L&lt;/span&gt;

    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;M&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;M&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;K&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;16&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;K&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;L&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;545140134&lt;/span&gt;
        &lt;span class="n"&gt;X&lt;/span&gt; &lt;span class="o"&gt;*=&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;262537412640768000&lt;/span&gt;
        &lt;span class="n"&gt;S&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;decimal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Decimal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;M&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;L&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;X&lt;/span&gt;

    &lt;span class="n"&gt;pi&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;C&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;S&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;pi&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I wrote a simple CLI to test this out:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;#!/usr/bin/env python3
&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;argparse&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;lib&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;compute_pi&lt;/span&gt;

&lt;span class="n"&gt;parser&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;argparse&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;ArgumentParser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Print n digits of pi.&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;parser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_argument&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;num_digits&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;metavar&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;N&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;help&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;no. of digits of pi to print&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;args&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;parser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse_args&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;compute_pi&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;num_digits&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here's the CLI in action:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;gt; ./pi.py 30
3.141592653589741586517727315459

&amp;gt; ./pi.py 300
3.141592653589741586517727315457865035780252691261563179943288214795808630531389642185274931230804430454419117074147967105366083976712333542218321180274249883145873143454428446008580088034341219473373000151443532721504141865178673966393142941520166862874509797611548477147655085787688540025728361617601
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The complete source code is &lt;a href="https://github.com/parambirs/n-digits-of-pi"&gt;available in this Github repository&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>pi</category>
      <category>python</category>
      <category>chudnovsky</category>
      <category>todayilearned</category>
    </item>
    <item>
      <title>TIL - Unix shells have a $RANDOM env variable</title>
      <dc:creator>Parambir Singh</dc:creator>
      <pubDate>Tue, 09 Apr 2019 21:23:43 +0000</pubDate>
      <link>https://dev.to/parambirs/til-unix-shells-have-a-random-env-variable-14f2</link>
      <guid>https://dev.to/parambirs/til-unix-shells-have-a-random-env-variable-14f2</guid>
      <description>&lt;p&gt;Ever wanted to add some randomness to your shell script? No I don't mean to make them flaky! &lt;/p&gt;

&lt;p&gt;Unix shells provide a &lt;code&gt;$RANDOM&lt;/code&gt; environment variable that we can use in our shell commands or scripts:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;% echo $RANDOM 
21290
% echo $RANDOM
8367
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;em&gt;seed&lt;/em&gt; for the random number generator can be changed as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;% RANDOM=12345
% echo $RANDOM
5758
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Generating random numbers in a range
&lt;/h3&gt;

&lt;p&gt;We can use &lt;code&gt;awk&lt;/code&gt; for generating random integers in a given range. For example, to generate a random number between 1 and 10 (inclusive):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;% awk -v seed=$RANDOM 'BEGIN{srand(seed); print int(rand()*10+1)}'
10
% awk -v seed=$RANDOM 'BEGIN{srand(seed); print int(rand()*10+1)}'
4
% awk -v seed=$RANDOM 'BEGIN{srand(seed); print int(rand()*10+1)}'
1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  More details at:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="http://srufaculty.sru.edu/david.dailey/unix/random_numbers.htm"&gt;http://srufaculty.sru.edu/david.dailey/unix/random_numbers.htm&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>unix</category>
      <category>sh</category>
      <category>bash</category>
      <category>zsh</category>
    </item>
    <item>
      <title>How to write a Haskell web service (from scratch) - Part 3</title>
      <dc:creator>Parambir Singh</dc:creator>
      <pubDate>Mon, 22 Oct 2018 19:48:50 +0000</pubDate>
      <link>https://dev.to/parambirs/how-to-write-a-haskell-web-servicefrom-scratch---part-3-5en6</link>
      <guid>https://dev.to/parambirs/how-to-write-a-haskell-web-servicefrom-scratch---part-3-5en6</guid>
      <description>&lt;p&gt;&lt;em&gt;This is the third part of a hands-on guide on creating a Haskell based web service. No previous knowledge of haskell is required. However, basic understanding of RESTful web services is assumed. Other posts in this series: &lt;a href="https://dev.to/parambirs/how-to-write-a-dockerized-haskell-web-servicefrom-scratch---part-1-3m7c"&gt;part 1&lt;/a&gt;, &lt;a href="https://dev.to/parambirs/how-to-write-a-haskell-web-servicefrom-scratch---part-2-6pi"&gt;part 2&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  3. Run a basic Haskell web app using Scotty
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Introducing &lt;a href="https://github.com/scotty-web/scotty" rel="noopener noreferrer"&gt;Scotty&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;There are many web frameworks available for Haskell: Yesod, Snap, Scotty, etc. I chose Scotty over others as it seemed easier to get started with.&lt;/p&gt;

&lt;p&gt;We’ll write a simple web service that responds to various HTTP request types (GET, PUT, POST, DELETE). We’ll see how to get request headers, path parameters and form fields and how to respond with plain-text, html or JSON response.&lt;/p&gt;

&lt;h2&gt;
  
  
  Initialise Cabal
&lt;/h2&gt;

&lt;p&gt;Let’s initialise a cabal app for our web service. I’ve mostly chosen the default options. Two notable exceptions include:&lt;br&gt;
license: 9) MIT&lt;br&gt;
source directory: 2) server&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;% mkdir scotty-webapp-example
% cd scotty-webapp-example
% cabal sandbox init
Writing a default package environment file to
/Users/psingh/tmp/haskell/eac-articles/scotty-webapp-example/cabal.sandbox.config
Using an existing sandbox located at
/Users/psingh/tmp/haskell/eac-articles/scotty-webapp-example/.cabal-sandbox
% cabal init
Package name? [default: scotty-webapp-example]
Package version? [default: 0.1.0.0]
...
...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Write the server code
&lt;/h2&gt;

&lt;p&gt;Since we told &lt;code&gt;cabal&lt;/code&gt; earlier that our main module for the executable will be &lt;code&gt;Main.hs&lt;/code&gt;, and that it will live inside the &lt;code&gt;server&lt;/code&gt; folder, let’s add &lt;code&gt;server/Main.hs&lt;/code&gt; file to our source.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="cp"&gt;{-# LANGUAGE OverloadedStrings #-}&lt;/span&gt;
&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;Web.Scotty&lt;/span&gt;
&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;Network.HTTP.Types&lt;/span&gt;

&lt;span class="n"&gt;main&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;scotty&lt;/span&gt; &lt;span class="mi"&gt;3000&lt;/span&gt; &lt;span class="o"&gt;$&lt;/span&gt; &lt;span class="kr"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;get&lt;/span&gt; &lt;span class="s"&gt;"/"&lt;/span&gt; &lt;span class="o"&gt;$&lt;/span&gt; &lt;span class="kr"&gt;do&lt;/span&gt;                         &lt;span class="c1"&gt;-- handle GET request on "/" URL&lt;/span&gt;
    &lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="s"&gt;"This was a GET request!"&lt;/span&gt;     &lt;span class="c1"&gt;-- send 'text/plain' response&lt;/span&gt;
  &lt;span class="n"&gt;delete&lt;/span&gt; &lt;span class="s"&gt;"/"&lt;/span&gt; &lt;span class="o"&gt;$&lt;/span&gt; &lt;span class="kr"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;html&lt;/span&gt; &lt;span class="s"&gt;"This was a DELETE request!"&lt;/span&gt;  &lt;span class="c1"&gt;-- send 'text/html' response&lt;/span&gt;
  &lt;span class="n"&gt;post&lt;/span&gt; &lt;span class="s"&gt;"/"&lt;/span&gt; &lt;span class="o"&gt;$&lt;/span&gt; &lt;span class="kr"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="s"&gt;"This was a POST request!"&lt;/span&gt;
  &lt;span class="n"&gt;put&lt;/span&gt; &lt;span class="s"&gt;"/"&lt;/span&gt; &lt;span class="o"&gt;$&lt;/span&gt; &lt;span class="kr"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="s"&gt;"This was a PUT request!"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can probably figure out, this code will start a server on port 3000 and:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;For a &lt;code&gt;GET&lt;/code&gt; request on the &lt;code&gt;/&lt;/code&gt; path, the server will respond with an HTML response with the content “This was a GET request!”&lt;/li&gt;
&lt;li&gt;For a &lt;code&gt;DELETE&lt;/code&gt; request on the &lt;code&gt;/&lt;/code&gt; path, the server will respond with a ‘plain-text’ response with the content “This was a DELETE request!”&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Add dependencies
&lt;/h2&gt;

&lt;p&gt;Let’s add a dependency for &lt;code&gt;scotty&lt;/code&gt; and &lt;code&gt;http-types&lt;/code&gt; libraries in our cabal file.&lt;/p&gt;

&lt;p&gt;This is how the build-depends segment of the scotty-webapp-example.cabal files looks right now:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="n"&gt;build&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;depends&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;base&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt;&lt;span class="mf"&gt;4.8&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="mf"&gt;4.9&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Change it to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="n"&gt;build&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;depends&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;base&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt;&lt;span class="mf"&gt;4.8&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="mf"&gt;4.9&lt;/span&gt;
             &lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;scotty&lt;/span&gt;
             &lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;types&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, run &lt;code&gt;cabal install&lt;/code&gt; to add the dependencies into your sandbox followed by &lt;code&gt;cabal run&lt;/code&gt; to run the server.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;% cabal install
Resolving dependencies…
Notice: installing into a sandbox located at
/Users/psingh/tmp/haskell/eac-articles/scotty-webapp-example/.cabal-sandbox
Configuring ansi-terminal-0.6.2.3…
Configuring appar-0.1.4…
…
…
% cabal run
Package has never been configured. Configuring with default flags. If this fails, please run configure manually.
Resolving dependencies…
Configuring scotty-webapp-example-0.1.0.0…
Preprocessing executable ‘scotty-webapp-example’ for
scotty-webapp-example-0.1.0.0…
[1 of 1] Compiling Main ( server/Main.hs, dist/build/scotty-webapp-example/scotty-webapp-example-tmp/Main.o )
Linking dist/build/scotty-webapp-example/scotty-webapp-example …
Running scotty-webapp-example…
Setting phasers to stun… (port 3000) (ctrl-c to quit)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The server will be running now on port 3000. Let’s verify that (using the excellent &lt;a href="https://github.com/jkbrzt/httpie" rel="noopener noreferrer"&gt;http&lt;/a&gt; tool:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;% http delete :3000
HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8
Date: Mon, 14 Sep 2015 05:44:57 GMT
Server: Warp/3.1.3
Transfer-Encoding: chunked
This was a DELETE request!
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Great!&lt;/p&gt;

&lt;h2&gt;
  
  
  Handling more complex requests
&lt;/h2&gt;

&lt;p&gt;Let’s add a few more handlers to handle different kinds of requests. Add the following to &lt;code&gt;server/Main.hs&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- set a header:&lt;/span&gt;
&lt;span class="n"&gt;post&lt;/span&gt; &lt;span class="s"&gt;"/set-headers"&lt;/span&gt; &lt;span class="o"&gt;$&lt;/span&gt; &lt;span class="kr"&gt;do&lt;/span&gt;
 &lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="n"&gt;status302&lt;/span&gt;  &lt;span class="c1"&gt;-- Respond with HTTP 302 status code&lt;/span&gt;
 &lt;span class="n"&gt;setHeader&lt;/span&gt; &lt;span class="s"&gt;"Location"&lt;/span&gt; &lt;span class="s"&gt;"http://www.google.com.au"&lt;/span&gt;
&lt;span class="c1"&gt;-- named parameters:&lt;/span&gt;
&lt;span class="n"&gt;get&lt;/span&gt; &lt;span class="s"&gt;"/askfor/:word"&lt;/span&gt; &lt;span class="o"&gt;$&lt;/span&gt; &lt;span class="kr"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;w&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="n"&gt;param&lt;/span&gt; &lt;span class="s"&gt;"word"&lt;/span&gt;
  &lt;span class="n"&gt;html&lt;/span&gt; &lt;span class="o"&gt;$&lt;/span&gt; &lt;span class="n"&gt;mconcat&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"&amp;lt;h1&amp;gt;You asked for "&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;", you got it!&amp;lt;/h1&amp;gt;"&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="c1"&gt;-- unnamed parameters from a query string or a form:&lt;/span&gt;
&lt;span class="n"&gt;post&lt;/span&gt; &lt;span class="s"&gt;"/submit"&lt;/span&gt; &lt;span class="o"&gt;$&lt;/span&gt; &lt;span class="kr"&gt;do&lt;/span&gt;  &lt;span class="c1"&gt;-- e.g. http://server.com/submit?name=somename&lt;/span&gt;
 &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="n"&gt;param&lt;/span&gt; &lt;span class="s"&gt;"name"&lt;/span&gt;
 &lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;
&lt;span class="c1"&gt;-- match a route regardless of the method&lt;/span&gt;
&lt;span class="n"&gt;matchAny&lt;/span&gt; &lt;span class="s"&gt;"/all"&lt;/span&gt; &lt;span class="o"&gt;$&lt;/span&gt; &lt;span class="kr"&gt;do&lt;/span&gt;
 &lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="s"&gt;"matches all methods"&lt;/span&gt;
&lt;span class="c1"&gt;-- handler for when there is no matched route&lt;/span&gt;
&lt;span class="c1"&gt;-- (this should be the last handler because it matches all routes)&lt;/span&gt;
&lt;span class="n"&gt;notFound&lt;/span&gt; &lt;span class="o"&gt;$&lt;/span&gt; &lt;span class="kr"&gt;do&lt;/span&gt;
 &lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="s"&gt;"there is no such route."&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Encode/Decode JSON
&lt;/h2&gt;

&lt;p&gt;Most web services these days interact via JSON. Haskell provides a type safe way to encode/decode JSON strings using the &lt;a href=""&gt;Aeson&lt;/a&gt; library.&lt;/p&gt;

&lt;h3&gt;
  
  
  Defining the model
&lt;/h3&gt;

&lt;p&gt;Let’s create an &lt;code&gt;Article&lt;/code&gt; data type that could represent a news article for example. An article consists of 3 fields: anInteger id, a Text title and a Text bodyText. By making Article an instance of &lt;code&gt;FromJSON&lt;/code&gt; and &lt;code&gt;ToJSON&lt;/code&gt; typeclasses, we can use Aeson library for converting between JSON strings and Article objects. Add the following code to the file &lt;code&gt;server/Article.hs&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="cp"&gt;{-# LANGUAGE OverloadedStrings #-}&lt;/span&gt;
&lt;span class="kr"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;Article&lt;/span&gt; &lt;span class="kr"&gt;where&lt;/span&gt;
&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;Data.Text.Lazy&lt;/span&gt;
&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;Data.Text.Lazy.Encoding&lt;/span&gt;
&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;Data.Aeson&lt;/span&gt;
&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;Control.Applicative&lt;/span&gt;

&lt;span class="c1"&gt;-- Define the Article constructor&lt;/span&gt;
&lt;span class="c1"&gt;-- e.g. Article 12 "some title" "some body text"&lt;/span&gt;
&lt;span class="kr"&gt;data&lt;/span&gt; &lt;span class="kt"&gt;Article&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;Article&lt;/span&gt; &lt;span class="kt"&gt;Integer&lt;/span&gt; &lt;span class="kt"&gt;Text&lt;/span&gt; &lt;span class="kt"&gt;Text&lt;/span&gt; &lt;span class="c1"&gt;-- id title bodyText&lt;/span&gt;
     &lt;span class="kr"&gt;deriving&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Show&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


&lt;span class="c1"&gt;-- Tell Aeson how to create an Article object from JSON string.&lt;/span&gt;
&lt;span class="kr"&gt;instance&lt;/span&gt; &lt;span class="kt"&gt;FromJSON&lt;/span&gt; &lt;span class="kt"&gt;Article&lt;/span&gt; &lt;span class="kr"&gt;where&lt;/span&gt;
     &lt;span class="n"&gt;parseJSON&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Object&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;Article&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;$&amp;gt;&lt;/span&gt;
                            &lt;span class="n"&gt;v&lt;/span&gt; &lt;span class="o"&gt;.:?&lt;/span&gt; &lt;span class="s"&gt;"id"&lt;/span&gt; &lt;span class="o"&gt;.!=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;*&amp;gt;&lt;/span&gt; &lt;span class="c1"&gt;-- the field "id" is optional&lt;/span&gt;
                            &lt;span class="n"&gt;v&lt;/span&gt; &lt;span class="o"&gt;.:&lt;/span&gt;  &lt;span class="s"&gt;"title"&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;*&amp;gt;&lt;/span&gt;
                            &lt;span class="n"&gt;v&lt;/span&gt; &lt;span class="o"&gt;.:&lt;/span&gt;  &lt;span class="s"&gt;"bodyText"&lt;/span&gt;


&lt;span class="c1"&gt;-- Tell Aeson how to convert an Article object to a JSON string.&lt;/span&gt;
&lt;span class="kr"&gt;instance&lt;/span&gt; &lt;span class="kt"&gt;ToJSON&lt;/span&gt; &lt;span class="kt"&gt;Article&lt;/span&gt; &lt;span class="kr"&gt;where&lt;/span&gt;
     &lt;span class="n"&gt;toJSON&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Article&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="n"&gt;title&lt;/span&gt; &lt;span class="n"&gt;bodyText&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
         &lt;span class="n"&gt;object&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"id"&lt;/span&gt; &lt;span class="o"&gt;.=&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                 &lt;span class="s"&gt;"title"&lt;/span&gt; &lt;span class="o"&gt;.=&lt;/span&gt; &lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                 &lt;span class="s"&gt;"bodyText"&lt;/span&gt; &lt;span class="o"&gt;.=&lt;/span&gt; &lt;span class="n"&gt;bodyText&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We’ll need to add a couple of routes to our Scotty router function to handle encoding and decoding Article types:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="n"&gt;main&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;scotty&lt;/span&gt; &lt;span class="mi"&gt;3000&lt;/span&gt; &lt;span class="o"&gt;$&lt;/span&gt; &lt;span class="kr"&gt;do&lt;/span&gt;

  &lt;span class="c1"&gt;-- get article (json)&lt;/span&gt;
  &lt;span class="n"&gt;get&lt;/span&gt; &lt;span class="s"&gt;"/article"&lt;/span&gt; &lt;span class="o"&gt;$&lt;/span&gt; &lt;span class="kr"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;json&lt;/span&gt; &lt;span class="o"&gt;$&lt;/span&gt; &lt;span class="kt"&gt;Article&lt;/span&gt; &lt;span class="mi"&gt;13&lt;/span&gt; &lt;span class="s"&gt;"caption"&lt;/span&gt; &lt;span class="s"&gt;"content"&lt;/span&gt; &lt;span class="c1"&gt;-- Call Article constructor and encode the result as JSON&lt;/span&gt;

  &lt;span class="c1"&gt;-- post article (json)&lt;/span&gt;
  &lt;span class="n"&gt;post&lt;/span&gt; &lt;span class="s"&gt;"/article"&lt;/span&gt; &lt;span class="o"&gt;$&lt;/span&gt; &lt;span class="kr"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;article&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="n"&gt;jsonData&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;ActionM&lt;/span&gt; &lt;span class="kt"&gt;Article&lt;/span&gt; &lt;span class="c1"&gt;-- Decode body of the POST request as an Article object&lt;/span&gt;
    &lt;span class="n"&gt;json&lt;/span&gt; &lt;span class="n"&gt;article&lt;/span&gt;                           &lt;span class="c1"&gt;-- Send the encoded object back as JSON&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We’ll also need to add a couple of dependencies to &lt;code&gt;scotty-webapp-example.cabal&lt;/code&gt; file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="n"&gt;build&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;depends&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;base&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt;&lt;span class="mf"&gt;4.8&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="mf"&gt;4.9&lt;/span&gt;
             &lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;scotty&lt;/span&gt;
             &lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;types&lt;/span&gt;
             &lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt;
             &lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;aeson&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Test JSON encoding/decoding
&lt;/h3&gt;

&lt;p&gt;Let’s fire up Scotty and see if it can handle JSON properly:&lt;/p&gt;

&lt;h4&gt;
  
  
  GET /article
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;% http get :3000/article
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Date: Mon, 14 Sep 2015 06:51:17 GMT
Server: Warp/3.1.3
Transfer-Encoding: chunked
{
  “bodyText”: “content”,
  “id”: 13,
  “title”: “caption”
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  POST /article
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;% http post :3000/article id:=23 title=”new caption” bodyText=”some content”
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Date: Mon, 14 Sep 2015 06:56:57 GMT
Server: Warp/3.1.3
Transfer-Encoding: chunked
{
  “bodyText”: “some content”,
  “id”: 23,
  “title”: “new caption”
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Source
&lt;/h2&gt;

&lt;p&gt;The complete source for this section is available on &lt;a href="https://github.com/parambirs/hello-scotty/tree/with-json-types" rel="noopener noreferrer"&gt;github&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Finally
&lt;/h1&gt;

&lt;p&gt;I hope you found this tutorial useful. Please let me know if something didn’t work for you or if I missed documenting any step.&lt;/p&gt;

</description>
      <category>haskell</category>
      <category>rest</category>
      <category>scotty</category>
      <category>cabal</category>
    </item>
    <item>
      <title>How to write a Haskell web service (from scratch) - Part 2</title>
      <dc:creator>Parambir Singh</dc:creator>
      <pubDate>Mon, 22 Oct 2018 19:47:17 +0000</pubDate>
      <link>https://dev.to/parambirs/how-to-write-a-haskell-web-servicefrom-scratch---part-2-6pi</link>
      <guid>https://dev.to/parambirs/how-to-write-a-haskell-web-servicefrom-scratch---part-2-6pi</guid>
      <description>&lt;p&gt;&lt;em&gt;This is the second part of a hands-on guide on creating a Haskell based web service. No previous knowledge of haskell is required. However, basic understanding of RESTful web services is assumed. Other posts in this series: &lt;a href="https://dev.to/parambirs/how-to-write-a-dockerized-haskell-web-servicefrom-scratch---part-1-3m7c"&gt;part 1&lt;/a&gt;, &lt;a href="https://dev.to/parambirs/how-to-write-a-haskell-web-servicefrom-scratch---part-3-5en6?"&gt;part 3&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  2. Build and package a simple app using cabal
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Introducing Cabal
&lt;/h2&gt;

&lt;p&gt;Cabal (Common Architecture for Building Applications and Libraries) is a system for building and packaging Haskell libraries and programs. Think of it as Haskell’s equivalent of Python’s &lt;code&gt;pip&lt;/code&gt;, Node’s &lt;code&gt;npm&lt;/code&gt; and Scala’s &lt;code&gt;sbt&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Before we get started, make sure that you have &lt;code&gt;cabal&lt;/code&gt; installed and on the system path:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;% cabal — version
cabal-install version 1.22.6.0
using version 1.22.4.0 of the Cabal library
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Create a cabal app
&lt;/h2&gt;

&lt;p&gt;Cabal makes it easy to build, package and test your application. It’s also straightforward to add dependencies on other libraries that cabal will fetch for you.&lt;/p&gt;

&lt;p&gt;It is possible that different Haskell apps have dependencies on different versions of the same library. To prevent conflicts in your global Haskell environment, it’s a good idea to create a sandbox for your app. Cabal will then install the dependent libraries inside the sandbox.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;% mkdir cabal-example
% cd cabal-example
% cabal sandbox init
Writing a default package environment file to
/Users/psingh/tmp/haskell/eac-articles/cabal
example/cabal.sandbox.config
Creating a new sandbox at
/Users/psingh/tmp/haskell/eac-articles/cabal-example/.cabal-sandbox
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, we can initialise our app. The easiest way to create a cabal app is using the &lt;code&gt;cabal init&lt;/code&gt; command. Follow the prompts and cabal will generate the config file for you. Here’s an example interaction on my system:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;% cabal init
Package name? [default: cabal-example]
Package version? [default: 0.1.0.0]
Please choose a license:
* 1) (none)
2) GPL-2
3) GPL-3
4) LGPL-2.1
5) LGPL-3
6) AGPL-3
7) BSD2
8) BSD3
9) MIT
10) ISC
11) MPL-2.0
12) Apache-2.0
13) PublicDomain
14) AllRightsReserved
15) Other (specify)
Your choice? [default: (none)] 9
Author name? [default: Parambir Singh]
Maintainer email? [default: user@domain.com]
Project homepage URL?
Project synopsis?
Project category:
* 1) (none)
2) Codec
3) Concurrency
4) Control
5) Data
6) Database
7) Development
8) Distribution
9) Game
10) Graphics
11) Language
12) Math
13) Network
14) Sound
15) System
16) Testing
17) Text
18) Web
19) Other (specify)
Your choice? [default: (none)]
What does the package build:
1) Library
2) Executable
Your choice? 2
What is the main module of the executable:
* 1) Main.hs (does not yet exist)
2) Main.lhs (does not yet exist)
3) Other (specify)
Your choice? [default: Main.hs (does not yet exist)] 1
What base language is the package written in:
* 1) Haskell2010
2) Haskell98
3) Other (specify)
Your choice? [default: Haskell2010] 1
Include documentation on what each field means (y/n)? [default: n] n
Source directory:
* 1) (none)
2) src
3) Other (specify)
Your choice? [default: (none)] 1
Guessing dependencies…
Generating LICENSE…
Generating Setup.hs…
Generating cabal-example.cabal…
Warning: no synopsis given. You should edit the .cabal file and add 
one.
You may want to edit the .cabal file and add a Description field.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You will now have a &lt;code&gt;cabal-example.cabal&lt;/code&gt; file in your source directory. Remember that we selected &lt;code&gt;Main.hs&lt;/code&gt; as our main module during the &lt;code&gt;cabal init&lt;/code&gt; process. Add a &lt;code&gt;Main.hs&lt;/code&gt; file now to the root of your source folder with the following content:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="n"&gt;c2f&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;32&lt;/span&gt;
&lt;span class="n"&gt;main&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kr"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;print&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c2f&lt;/span&gt; &lt;span class="mi"&gt;37&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Running your cabal app (cabal run)
&lt;/h2&gt;

&lt;p&gt;To run your app, use the &lt;code&gt;cabal run&lt;/code&gt; command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;% cabal run
Package has never been configured. Configuring with default flags. If this fails, please run configure manually.
Resolving dependencies…
Configuring cabal-example-0.1.0.0…
Preprocessing executable ‘cabal-example’ for cabal-example-0.1.0.0…
[1 of 1] Compiling Main ( Main.hs, dist/build/cabal-example/cabal-example-tmp/Main.o )
Linking dist/build/cabal-example/cabal-example …
Running cabal-example…
98.6
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Other useful cabal commands
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;cabal clean&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Removes the generated artifacts (executables etc.)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;% cabal clean
cleaning…
cabal build
Compiles and links your source code to generate the executable.
% cabal build
Package has never been configured. Configuring with default flags. If this fails, please run configure manually.
Resolving dependencies…
Configuring cabal-example-0.1.0.0…
Building cabal-example-0.1.0.0…
Preprocessing executable ‘cabal-example’ for cabal-example-0.1.0.0…
[1 of 1] Compiling Main ( Main.hs, dist/build/cabal-example/cabal-example-tmp/Main.o )
Linking dist/build/cabal-example/cabal-example …
Run the generated executable:
% ./dist/build/cabal-example/cabal-example
98.6
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;code&gt;cabal install&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Installs the generated artifact into the cabal sandbox. This is somewhat similar to &lt;code&gt;mvn install&lt;/code&gt; in Java world.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;% cabal install
Resolving dependencies…
Notice: installing into a sandbox located at
/Users/psingh/tmp/haskell/eac-articles/cabal-example/.cabal-sandbox
Configuring cabal-example-0.1.0.0…
Building cabal-example-0.1.0.0…
Installed cabal-example-0.1.0.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;code&gt;cabal repl&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Starts a &lt;code&gt;ghci&lt;/code&gt; session for your project (i.e. with your modules loaded). You can easily test your functions here.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;% cabal repl
Preprocessing executable ‘cabal-example’ for cabal-example-0.1.0.0…
GHCi, version 7.10.2: http://www.haskell.org/ghc/ :? for help
[1 of 1] Compiling Main ( Main.hs, interpreted )
Ok, modules loaded: Main.
*Main&amp;gt; c2f 37 — call the c2f function defined in our Main.hs file
98.6
*Main&amp;gt; main — yes, this is the main function we defined in Main.hs
98.6
*Main&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  cabal update
&lt;/h3&gt;

&lt;p&gt;Downloads the latest package list for cabal. It’s useful to run &lt;code&gt;cabal update&lt;/code&gt; before running &lt;code&gt;cabal init&lt;/code&gt; or &lt;code&gt;cabal install&lt;/code&gt; to make sure that cabal has knowledge about the latest packages&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;% cabal update
Downloading the latest package list from hackage.haskell.org
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Source
&lt;/h2&gt;

&lt;p&gt;The complete source for this section is available on &lt;a href="https://github.com/parambirs/hello-cabal" rel="noopener noreferrer"&gt;github&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Next…
&lt;/h1&gt;

&lt;p&gt;In &lt;a href="https://dev.to/parambirs/how-to-write-a-haskell-web-servicefrom-scratch---part-3-5en6"&gt;Part 3&lt;/a&gt;, We’ll write a simple web app using the Scotty web framework for Haskell.&lt;/p&gt;

</description>
      <category>haskell</category>
      <category>rest</category>
      <category>scotty</category>
      <category>cabal</category>
    </item>
    <item>
      <title>How to write a Haskell web service (from scratch) - Part 1</title>
      <dc:creator>Parambir Singh</dc:creator>
      <pubDate>Fri, 12 Oct 2018 21:01:48 +0000</pubDate>
      <link>https://dev.to/parambirs/how-to-write-a-dockerized-haskell-web-servicefrom-scratch---part-1-3m7c</link>
      <guid>https://dev.to/parambirs/how-to-write-a-dockerized-haskell-web-servicefrom-scratch---part-1-3m7c</guid>
      <description>&lt;p&gt;&lt;em&gt;This is the first part of a hands-on guide on creating a Haskell based web service. No previous knowledge of haskell is required. However, basic understanding of RESTful web services is assumed. Other posts in this series: &lt;a href="https://dev.to/parambirs/how-to-write-a-haskell-web-servicefrom-scratch---part-2-6pi"&gt;part 2&lt;/a&gt;, &lt;a href="https://dev.to/parambirs/how-to-write-a-haskell-web-servicefrom-scratch---part-3-5en6"&gt;part 3&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Over the last couple of weeks, I spent some time creating a simple Haskell web application. As it is with every new language or platform, I had to set up and understand a lot of things to get my app up and running. I’m sharing my experience here, hoping that it will help others who might be inclined to get into the Haskell world.&lt;/p&gt;

&lt;p&gt;We’ll go through the following 3 steps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Set up the development environment&lt;/li&gt;
&lt;li&gt;Build and package a simple app using &lt;code&gt;cabal&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Run a basic Haskell web app using Scotty&lt;/li&gt;
&lt;/ul&gt;




&lt;h1&gt;
  
  
  1. Set up the development environment
&lt;/h1&gt;

&lt;p&gt;&lt;em&gt;You may skip this step if you already have &lt;code&gt;ghc&lt;/code&gt; and &lt;code&gt;cabal&lt;/code&gt; installed on your system.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Install the Haskell Platform (GHC)
&lt;/h2&gt;

&lt;p&gt;GHC is the Glasgow Haskell Compiler package which provides you the compiler (&lt;code&gt;ghc&lt;/code&gt;) as well as a REPL (&lt;code&gt;ghci&lt;/code&gt;). Cabal is Haskell’s package manager and works similar to &lt;code&gt;npm&lt;/code&gt; (NodeJS), &lt;code&gt;sbt&lt;/code&gt; (Scala) and &lt;code&gt;maven&lt;/code&gt; (Java).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;% brew update
% brew install ghc cabal-install
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Haskell REPL (&lt;code&gt;ghci&lt;/code&gt;)
&lt;/h2&gt;

&lt;p&gt;Next, we’ll start the Haskell REPL which is called &lt;code&gt;ghci&lt;/code&gt; and get comfortable with a bit of Haskell syntax.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;% ghci
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let’s define two simple functions that convert temperature values between celsius and fahrenheit:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Prelude&amp;gt; let f2c f = (f — 32) * 5 / 9
Prelude&amp;gt; let c2f c = (c * 9/5) + 32
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, we can call these functions to get converted temperatures:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Prelude&amp;gt; f2c 800
426.6666666666667
Prelude&amp;gt; c2f 100
212.0
Prelude&amp;gt; c2f 37
98.6
Prelude&amp;gt; &amp;lt;Ctrl+D&amp;gt; — To exit
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Run Haskell Scripts (&lt;code&gt;runhaskell&lt;/code&gt;)
&lt;/h2&gt;

&lt;p&gt;We’ll move these function definitions to a haskell source file and define a main method that prints the converted temperature value.&lt;/p&gt;

&lt;p&gt;Copy the following code into a file named &lt;code&gt;c2f.hs&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="n"&gt;c2f&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;32&lt;/span&gt;
&lt;span class="n"&gt;main&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kr"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;print&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c2f&lt;/span&gt; &lt;span class="mi"&gt;37&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Note: We used &lt;code&gt;let&lt;/code&gt; for defining functions inside &lt;code&gt;ghci&lt;/code&gt;. When writing Haskell source files, you don’t require &lt;code&gt;let&lt;/code&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Run the script from the command line using &lt;code&gt;runhaskell&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;% runhaskell c2f.hs
98.6
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Build an executable
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;runhaskell&lt;/code&gt; makes the development cycle easier when you are writing a Haskell application. But you can also create executable files using the &lt;code&gt;ghc&lt;/code&gt; compiler. Let’s convert our script to a binary and then run it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;% ghc c2f.hs
[1 of 1] Compiling Main ( c2f.hs, c2f.o )
Linking c2f …

% ls
c2f c2f.hi c2f.hs c2f.o

% ./c2f
98.6
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Load your source files into &lt;code&gt;ghci&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;You can load external source files into &lt;code&gt;ghci&lt;/code&gt; by using the &lt;code&gt;:load&lt;/code&gt; or &lt;code&gt;:l&lt;/code&gt; command. Let’s start a &lt;code&gt;ghci&lt;/code&gt; session and load our &lt;code&gt;Main.hs&lt;/code&gt; file so that we can use the &lt;code&gt;c2f&lt;/code&gt; function inside the REPL:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;% ghci
GHCi, version 7.10.2: http://www.haskell.org/ghc/ :? for help
Prelude&amp;gt; :load Main.hs
[1 of 1] Compiling Main ( Main.hs, interpreted )
Ok, modules loaded: Main.
*Main&amp;gt; c2f 37
98.6
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now that our development environment is set up, in &lt;a href="https://dev.to/parambirs/how-to-write-a-haskell-web-servicefrom-scratch---part-2-6pi"&gt;part 2&lt;/a&gt; we’ll move on to building a simple app using &lt;code&gt;cabal&lt;/code&gt; which is Haskell’s package manager.&lt;/p&gt;

</description>
      <category>haskell</category>
      <category>rest</category>
      <category>scotty</category>
      <category>cabal</category>
    </item>
    <item>
      <title>A Tour of Go – Exercise Solutions</title>
      <dc:creator>Parambir Singh</dc:creator>
      <pubDate>Mon, 22 Feb 2016 22:20:00 +0000</pubDate>
      <link>https://dev.to/parambirs/a-tour-of-go-exercise-solutions-141l</link>
      <guid>https://dev.to/parambirs/a-tour-of-go-exercise-solutions-141l</guid>
      <description>&lt;p&gt;I spent the past weekend learning Go. &lt;a href="https://tour.golang.org/list"&gt;A Tour of Go&lt;/a&gt; is a great resource to quickly come up to speed with Go. It’s a very small language (the spec is only around 50 pages!) and is really easy to pick up if you are already familiar with languages like C, JavaScript, Java or C#. I really liked the exercises that were scattered around in the tour. The ones that I found interesting were:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://tour.golang.org/methods/23"&gt;rot13Reader&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://tour.golang.org/concurrency/8"&gt;Equivalent Binary Trees&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://tour.golang.org/concurrency/10"&gt;Web Crawler (the most interesting one!)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I’ve put up my solutions to all the exercises in a Github repository – &lt;a href="https://github.com/parambirs/atourofgo-exercises"&gt;https://github.com/parambirs/atourofgo-exercises&lt;/a&gt;. I’d be interested in seeing alternate solutions and discussing different approaches to solving these exercises in Go!&lt;/p&gt;

</description>
      <category>go</category>
    </item>
  </channel>
</rss>
