tag:blogger.com,1999:blog-34881934424484516532024-03-13T15:03:28.531-07:00Dananji's BlogDananji Withanahttp://www.blogger.com/profile/04345021233196010166noreply@blogger.comBlogger7125tag:blogger.com,1999:blog-3488193442448451653.post-17773600398814971872019-12-10T08:17:00.100-08:002023-12-11T07:07:55.831-08:00TEST<div id="iframecontainer">
<iframe title="Hayden Cello - Cello" src="//avalon-dev.dlib.indiana.edu:443/master_files/02870v844/embed" width="600" height="40" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>
</div>
<iframe title="Jazz Performance - Jazz" src="//avalon-staging.dlib.indiana.edu:443/master_files/2801pg34x/embed" width="600" height="40" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>
<iframe title="A day of Thanksgiving - Film 1/1 Part 1 (40000003425339)" src="https://purl.dlib.indiana.edu/iudl/media/178455b96j?urlappend=%2Fembed" width="600" height="450" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>
<video-js id="adssa">
<source src="https://iiif-react-media-player.netlify.app/lunchroom_manners/high/lunchroom_manners_1024kb.mp4">
</video-js>
<iframe title="Lunchroom Manners - Lunchroom Manners" src="https://purl.dlib.indiana.edu/iudl/media/2773865k62?urlappend=%2Fembed" width="600" height="450" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>
<iframe title=""Lunchroom Manners" - Lunchroom Manners" src="http://localhost:3000/master_files/9c67wm80s/embed" width="600" height="450" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>
<iframe title=""No Time"/"Until We're Free" - Sample video" src="http://localhost:3000/master_files/mg74qm08d/embed" width="600" height="337" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>
Dananji Withanahttp://www.blogger.com/profile/04345021233196010166noreply@blogger.com0tag:blogger.com,1999:blog-3488193442448451653.post-80531732919580759122016-03-29T00:45:00.002-07:002016-05-09T17:12:19.687-07:00Publish a Haskell package in Hackage<div dir="ltr" style="text-align: left;" trbidi="on">
<div style="text-align: justify;">
Haskell being in the 38th position in the Programming Community Index, it has an immense number of packages providing a variety of functionalities for its developers. You can find the full list of Haskell packages in <a href="https://hackage.haskell.org/packages/" target="_blank">here</a>. Even though, there are such a huge number of packages many new packages are added to Hackage frequently. </div>
<br />
<div style="text-align: justify;">
First, let's understand what does it mean by 'package' in Haskell. A package is the unit of distribution for the Cabal, which is a system for building and packaging Haskell libraries and programs. Its purpose in life, when installed, is to make available some Haskell modules to be imported into a Haskell program a developer is writing.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Before starting off with package development, you need to understand couple of basic rules and regulations in a Haskell package. The main concern in developing a package is that, it should be light-weighted as much as possible, i.e. the build depends section in the cabal file should contain minimal dependencies to the other packages. And the other main thing, you need to be aware of is the documentation. Use 'Haddock' to build the necessary documentation of your package. Refer to this link to read more on the Haddock usage in your Haskell package.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Now that you have a basic understanding about the Haskell packages, let's get to work! </div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
First step is to make sure your program compiles without any errors. And then, it provides the expected output when run with the desired input parameters. </div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Then, create a comprehensive cabal file for your package. You can create a cabal file for your project by running <span style="font-family: "courier new" , "courier" , monospace;">'cabal init'</span><span style="font-family: inherit;"> in your terminal at the project directory. Once you have the basic structure, fill in the required fields of the cabal file using a text editor. After filling out fields, you can check whether your cabal file is correct by running </span><span style="font-family: "courier new" , "courier" , monospace;">'cabal check'</span><span style="font-family: inherit;"> in the terminal. If there are any missing fields, this command will point out them to you.</span></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
After that, use Haddock to build the necessary documentation for the code. To do this, you can type in <span style="font-family: "courier new" , "courier" , monospace;">'cabal haddock'</span><span style="font-family: inherit;"> in your terminal after navigating to the project directory. This command will output the document coverage of the code and points out the necessary places, which need to be updated.</span></div>
<div style="text-align: justify;">
<span style="font-family: inherit;"><br /></span></div>
<div style="text-align: justify;">
<span style="font-family: inherit;"><a href="http://3.bp.blogspot.com/-pbMkhL9MB6w/Vvog8_pLj5I/AAAAAAAAAv0/6k-UtvcKyzEfppWhHB1eDeKbF2WNCQAng/s1600/haddock.PNG" imageanchor="1"><img border="0" src="https://3.bp.blogspot.com/-pbMkhL9MB6w/Vvog8_pLj5I/AAAAAAAAAv0/6k-UtvcKyzEfppWhHB1eDeKbF2WNCQAng/s1600/haddock.PNG" /></a></span></div>
<br />
<div style="text-align: justify;">
If you don't have any idea how to create a comprehensive documentation for your package, just take a look at the available packages in Hackage and adapt those documentation styles to your package. </div>
<br />
<div style="text-align: justify;">
The next step is to create the tarball of your package content. First get your code, cabal file, README file and put them in a folder with the name <i>package-version. </i>For an example; foo-0.1.3.0. You can read more about the package version policy in Haskell in this <a href="https://wiki.haskell.org/Package_versioning_policy" target="_blank">link</a>. </div>
<div style="text-align: justify;">
Since I'm using Windows, I used <a href="http://www.7-zip.org/" target="_blank">7-Zip</a> to create a tarball. Following the instructions in their you can create the tarball for you package.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Then comes the part, where you upload the package to Hackage. In order to upload a package, you must have an account. You have to request an account by filling out the form in this <a href="http://hackage.haskell.org/users/register-request" target="_blank">link</a>. Once you have your account, log into your account.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
There are 2 package upload scenarios; upload a new package OR upload a new version of an existing package.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Scenario 1: Upload a new package.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
You can simply go to the upload link in your account, and click on 'Upload a package' leading you <a href="https://hackage.haskell.org/packages/upload" target="_blank">here</a>. You can upload you tarball here, and if there are no errors in your tarball structure this will upload the package candidate smoothly. Then go your user-account. Now you can see the uploaded package. If you can't find a link to go to your account, just search your username in the user-accounts list <a href="http://hackage.haskell.org/users/" target="_blank">here</a>. </div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Now go to your package and go to 'Maintainer's corner' and click on 'edit package information' which will take you to the publishing page as shown below;</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
</div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div style="text-align: justify;">
<a href="http://3.bp.blogspot.com/-EqgW84FMbw8/VvouTgcUn5I/AAAAAAAAAww/Jvoua-9IvAMQ8_u2OoXhWrM9LLbUgh0nQ/s1600/publish2.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="220" src="https://3.bp.blogspot.com/-EqgW84FMbw8/VvouTgcUn5I/AAAAAAAAAww/Jvoua-9IvAMQ8_u2OoXhWrM9LLbUgh0nQ/s640/publish2.png" width="640" /></a></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: left;">
<br />
<br />
Now you can publish the candidate by clicking on 'Publish candidate', making the package available for the other Haskell developers. </div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
Scenario 2: Upload a new version of an existing package</div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
In order to do this you should be part of the maintainer group of the package. Given that you are in the maintainer group, you can upload a package candidate following the above steps. But the most important thing to remember is that, you cannot upload the same version number again to Hackage.</div>
<div style="text-align: left;">
<br /></div>
<div style="text-align: left;">
There are many resources available in the internet, you can read to get a thorough understanding on the matter. Please do read and understand the procedure before you publish your package, because you can upload a package version once!</div>
<div style="text-align: left;">
<br /></div>
</div>
Dananji Withanahttp://www.blogger.com/profile/04345021233196010166noreply@blogger.com0tag:blogger.com,1999:blog-3488193442448451653.post-91497929836502078882016-03-21T04:37:00.000-07:002016-03-29T00:48:23.031-07:00Using Basic HTTP Authentication in Haskell<div dir="ltr" style="text-align: left;" trbidi="on">
<div style="text-align: justify;">
I have recently developed a Haskell library to interact with the <a href="http://mailchimp.com/" target="_blank">Mailchimp</a> JSON API version 2.0. This is the <a href="http://dananjiliyanage.blogspot.com/2015/07/develop-mailchimp-library-with-haskell.html" target="_blank">blog post</a> regarding the implementation of the said library. At the end of the blog post I stated, that I will try and update the library to support the version 3.0 of the JSON API. Since the version 2.0 is deprecated long ago and I had some free time in hand, I decided to develop the library to work with version 3.0 API calls. To read further more about the version 3.0 refer to this <a href="http://developer.mailchimp.com/documentation/mailchimp/guides/get-started-with-mailchimp-api-3/" target="_blank">link</a>.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
The major difference in version 3.0 API from the version 2.0 API you need to know in developing the library is that, the removal of API Key from the request body and introducing HTTP Basic Auth in addition to OAuth2. In this implementation, I have used Basic HTTP Auth imported from 'Network.HTTP.Conduit' module in 'http-conduit' package. For further reading on the differences between the two Mailchimp API versions, please follow this <a href="http://devs.mailchimp.com/blog/api-v3-0-officially-launched/" target="_blank">link</a>.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
The major component in developing the library for version 3.0 was to integrate Basic HTTP authentication with the API calls. In this post, I'll take you through the implementation of Basic HTTP Auth in the library.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
There are 2 basic HTTP requests we need to perform in this library. They are GET and POST requests. For GET requests, the request body is empty while for POST requests we need to send data along with the request. I have implemented 2 separate methods to perform these requests in the library. </div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
The POST requests in Mailchimp JSON API version 3.0 looks as follows;<br />
<br />
<div style="text-align: left;">
<span style="font-family: "courier new" , "courier" , monospace;">curl --request POST \</span></div>
<div style="text-align: left;">
<span style="font-family: "courier new" , "courier" , monospace;"> --url 'https://dc.api.mailchimp.com/3.0/campaigns' \</span></div>
<div style="text-align: left;">
<span style="font-family: "courier new" , "courier" , monospace;"> --user 'anystring:apikey' \</span></div>
<div style="text-align: left;">
<span style="font-family: "courier new" , "courier" , monospace;"> --header 'content-type:application/json' \</span></div>
<div style="text-align: left;">
<span style="font-family: "courier new" , "courier" , monospace;"> --data '{"recipients":{"list_id":"et43235dg"}, "type":"regular","settings":{"subject_line":"this is the subject","reply_to":"reply@gmail.com","from_name":"from Mailchimp"}}' \</span></div>
<div style="text-align: left;">
<span style="font-family: "courier new" , "courier" , monospace;"> --inlcude</span></div>
<br />
So there are two parts for the HTTP request, i.e. authenticate the user and send the json data to the given URL. I used the the 'applyBasicAuth' function in the 'Network.HTTP.Conduit' module. The type definition for this function is as follows;<br />
<br />
<span style="font-family: "courier new" , "courier" , monospace;">applyBasicAuth :: ByteString -> ByteString -> Request -> Request</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
The parameters are passed as <span style="font-family: "courier new" , "courier" , monospace;">'applyBasicAuth 'username' 'apiKey' $ fromJust $ parseUrl url'</span><span style="font-family: inherit;">. </span>Here, what 'applyBasicAuth' function does is attach a Basic Auth Header to the given Request.<br />
<br />
In Mailchimp the username for the HTTP authentication is 'anystring', so I have hard-coded it within the functions.<br />
<br />
Then we inject the json data to the request body of the resulting Request and the HTTP method to POST. Finally using 'httpLbs' method in 'Network.HTTP.Conduit' module we perform the action we intended. The full code snippet for this function is as follows;<br />
<br />
<a href="http://2.bp.blogspot.com/-d_lyZ7sIm-4/VvozMznGuAI/AAAAAAAAAxI/hjERF1ld7bkSokwTWZcEOVix_pRP1-VkQ/s1600/post.PNG" imageanchor="1"><img border="0" src="https://2.bp.blogspot.com/-d_lyZ7sIm-4/VvozMznGuAI/AAAAAAAAAxI/hjERF1ld7bkSokwTWZcEOVix_pRP1-VkQ/s1600/post.PNG" /></a><br />
<br />
For HTTP GET, the format of the request specified in Mailchimp JSON API version 3.0 is as follows;<br />
<br />
<div style="text-align: left;">
<span style="font-family: "courier new" , "courier" , monospace;">curl --request GET \</span></div>
<div style="text-align: left;">
<span style="font-family: "courier new" , "courier" , monospace;"> --url 'https://dc.api.mailchimp.com/3.0/lists' \</span></div>
<div style="text-align: left;">
<span style="font-family: "courier new" , "courier" , monospace;"> --user 'anystring:apikey'</span><br />
<br />
<span style="font-family: inherit;">This request retrieves data for all fields regarding each mailing list in the given account. But, if you want to receive only a couple of fields you can specify them in the request. </span>To receive only the list ID and name for each list in the account, the request can be modified as follows;<br />
<span style="font-family: inherit;"><br /></span>
<br />
<div style="text-align: left;">
<span style="font-family: "courier new" , "courier" , monospace;">curl --request GET \</span></div>
<div style="text-align: left;">
<span style="font-family: "courier new" , "courier" , monospace;"> --url 'https://dc.api.mailchimp.com/3.0/lists?fields=lists.id,lists.name' \</span></div>
<div style="text-align: left;">
<span style="font-family: "courier new" , "courier" , monospace;"> --user 'anystring:apikey'</span></div>
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="text-align: justify;">For the GET requests, what I have done is; remove json data injection for the initial request and setting the HTTP method as GET instead of POST. So the function to process HTTP GET request is as follows;</span></div>
<br />
<a href="http://1.bp.blogspot.com/-kvy8q4ZKGQQ/Vu_YkqKVCTI/AAAAAAAAAu4/CctxvR-ca0cscx02ixnr2WF7L1MLMpLEw/s1600/get.PNG" imageanchor="1"><img border="0" src="https://1.bp.blogspot.com/-kvy8q4ZKGQQ/Vu_YkqKVCTI/AAAAAAAAAu4/CctxvR-ca0cscx02ixnr2WF7L1MLMpLEw/s1600/get.PNG" /></a><br />
<br />
You can get the full program from my <a href="https://github.com/Dananji/MailchimpSimple" target="_blank">GitHub repository</a>. I hope this post will be helpful for you!! Enjoy :)<br />
<br />
<br /></div>
</div>
Dananji Withanahttp://www.blogger.com/profile/04345021233196010166noreply@blogger.com1tag:blogger.com,1999:blog-3488193442448451653.post-14201640907530756952015-08-23T20:41:00.000-07:002016-02-29T22:10:24.588-08:00Handling Dependencies in Haskell<div dir="ltr" style="text-align: left;" trbidi="on">
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
At each Haskell compilation using a .cabal file, the compiler checks for the dependencies and downloads them. This sometimes leads to duplication of installation/ re-installation, which eventually results in recursive dependencies and build errors of the application.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
This can be seen in couple of different ways, they are; </div>
<div style="text-align: justify;">
<br /></div>
<ul style="text-align: left;">
<li style="text-align: justify;">Recursive dependencies</li>
</ul>
<blockquote class="tr_bq">
<div style="text-align: justify;">
<span style="font-family: "courier new" , "courier" , monospace;">cabal: Error: some packages failed to install: snap-core-0.9.7.0 failed during the building phase.</span><span style="text-align: left;"> </span></div>
</blockquote>
<blockquote class="tr_bq">
<div style="text-align: justify;">
<span style="font-family: "courier new" , "courier" , monospace;">The exception was: ExitFailure 1</span></div>
</blockquote>
<ul style="text-align: left;">
<li style="text-align: justify;">Hidden packages/modules</li>
</ul>
<blockquote class="tr_bq">
<div style="text-align: left;">
<span style="font-family: "courier new" , "courier" , monospace;">SnapUtil.hs:26:18:</span></div>
<div style="text-align: left;">
<span style="font-family: "courier new" , "courier" , monospace;"> Could not find module ‘Safe’</span></div>
<div style="text-align: left;">
<span style="font-family: "courier new" , "courier" , monospace;"> It is a member of the hidden package ‘safe-0.3.9’.</span></div>
<div style="text-align: left;">
<span style="font-family: "courier new" , "courier" , monospace;"> Use -v to see a list of the files searched for.</span></div>
</blockquote>
<ul style="text-align: left;">
<li style="text-align: justify;">Uncertainty of the package by which a particular module is being imported</li>
</ul>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<blockquote class="tr_bq">
<br />
<div style="text-align: left;">
<span style="font-family: "courier new" , "courier" , monospace;"> CMD.hs:19:17:</span></div>
<div style="text-align: left;">
<span style="font-family: "courier new" , "courier" , monospace;"> Ambiguous occurrence ‘lookup’</span></div>
<div style="text-align: left;">
<span style="font-family: "courier new" , "courier" , monospace;"> It could refer to either ‘CMD.lookup’, defined at CMD.hs:12:20</span><span style="font-family: "courier new" , "courier" , monospace;"> </span><span style="font-family: "courier new" , "courier" , monospace;">or ‘Prelude.lookup’, </span><span style="text-align: left;"> </span></div>
</blockquote>
<blockquote class="tr_bq">
<div style="text-align: left;">
<span style="font-family: "courier new" , "courier" , monospace;"> imported from ‘Prelude’ at CMD.hs:3:8-10 </span><span style="font-family: "courier new" , "courier" , monospace;">(and originally defined in ‘GHC.List’)</span></div>
</blockquote>
<br />
<ul style="text-align: left;">
<li>Could not resolve dependencies, Backjump limit reached</li>
</ul>
<blockquote class="tr_bq">
<span style="font-family: "courier new" , "courier" , monospace;">cabal: Could not resolve dependencies:<br />trying: snap-0.14.0.6 (user goal)<br />......................<br />......................<br />Backjump limit reached (change with --max-backjumps)</span></blockquote>
<br />
<blockquote class="tr_bq">
</blockquote>
<blockquote class="tr_bq" style="text-align: justify;">
To solve them there are numerous ways. Here I'm going to share some methodologies I know to go around the above issues.</blockquote>
<ul style="text-align: left;">
<li style="text-align: justify;">Solution to recursive dependencies</li>
</ul>
<blockquote class="tr_bq">
<div style="text-align: justify;">
The reason behind recursive dependencies is; registering the same package in both System directory and User directory of cabal. In order to solve this you should take a look at the packages installed with the 'ghc-pkg list' command as follows;</div>
</blockquote>
<blockquote class="tr_bq" style="text-align: justify;">
It lists both System directory packages and User directory packages.</blockquote>
<div style="text-align: justify;">
<br /></div>
<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://3.bp.blogspot.com/-bcHnVv3DbOU/VYOrvDNV8AI/AAAAAAAAAag/T8MmibbMTd0/s1600/dep_3.PNG" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="183" src="http://3.bp.blogspot.com/-bcHnVv3DbOU/VYOrvDNV8AI/AAAAAAAAAag/T8MmibbMTd0/s400/dep_3.PNG" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">System directory packages</td></tr>
</tbody></table>
<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://1.bp.blogspot.com/-i0L89CqSeR0/VYOsNZ7KRmI/AAAAAAAAAao/Emorrkz83xE/s1600/dep_4.PNG" imageanchor="1" style="clear: left; margin-bottom: 1em; margin-left: auto; margin-right: auto;"><img border="0" height="155" src="http://1.bp.blogspot.com/-i0L89CqSeR0/VYOsNZ7KRmI/AAAAAAAAAao/Emorrkz83xE/s400/dep_4.PNG" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">User directory packages</td></tr>
</tbody></table>
<div style="text-align: justify;">
<br /></div>
<blockquote class="tr_bq">
<div style="text-align: justify;">
If you can eye the repeating packages you can unregister them using;</div>
</blockquote>
<blockquote class="tr_bq">
<div style="text-align: justify;">
<span style="font-family: "courier new" , "courier" , monospace;">'ghc-pkg unregister <packageName | packageName-version>'</span></div>
</blockquote>
<ul style="text-align: left;">
<li style="text-align: justify;">Solution to shadowed packages/ modules</li>
</ul>
<div>
<blockquote class="tr_bq" style="text-align: justify;">
In case of a hidden package you can see in the package list in parenthesis as follows;</blockquote>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-6YdPNBDXOm0/VdRRxm2jyhI/AAAAAAAAAh0/OD4X-Kv7YVc/s1600/dep_5.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="109" src="http://3.bp.blogspot.com/-6YdPNBDXOm0/VdRRxm2jyhI/AAAAAAAAAh0/OD4X-Kv7YVc/s400/dep_5.PNG" width="400" /></a></div>
<div style="text-align: justify;">
<br /></div>
<blockquote class="tr_bq" style="text-align: justify;">
Here the packages 'monad-tf-0.1.0.2' and 'network-uri-2.6.0.3' are hidden. You can expose those packages using;</blockquote>
<blockquote class="tr_bq">
<span style="font-family: "courier new" , "courier" , monospace;">'ghc-pkg expose <packageName | packageName-version>'</span></blockquote>
<blockquote class="tr_bq" style="text-align: justify;">
In a scenario where there are hidden modules, there is no solid solution in order to use the same module in your code except for switching to another module in a different package, because this is done by the author of the package at the time of publishing it. You can check this using the following command for the specific package, which the module is imported from;</blockquote>
<blockquote class="tr_bq">
<span style="font-family: "courier new" , "courier" , monospace;">'ghc-pkg describe <packageName>'</span></blockquote>
<blockquote class="tr_bq">
The result of that command for the 'http-client'</blockquote>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-6mJUHKP9ROA/VdRT-XeW8pI/AAAAAAAAAiI/exxP6bezmpU/s1600/dep_6.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="220" src="http://4.bp.blogspot.com/-6mJUHKP9ROA/VdRT-XeW8pI/AAAAAAAAAiI/exxP6bezmpU/s400/dep_6.PNG" width="400" /></a></div>
<br />
<blockquote class="tr_bq">
Here, you can see the hidden modules and the exposed-modules from the package. </blockquote>
</div>
<ul style="text-align: left;">
<li style="text-align: justify;">Solution to uncertainty of package by which a particular module is being imported</li>
</ul>
<blockquote class="tr_bq" style="text-align: justify;">
The best way to solve this is to import packages with the "qualified" tag when you are in doubt whether there are multiple packages importing the methods with the same name. </blockquote>
<blockquote class="tr_bq" style="text-align: justify;">
Another way is to import the packages as follows;</blockquote>
<blockquote class="tr_bq" style="text-align: justify;">
'<span style="font-family: "courier new" , "courier" , monospace;">import Data.Aeson as DA'</span></blockquote>
<blockquote class="tr_bq" style="text-align: justify;">
That way you can always import the methods from the respective package like this,</blockquote>
<blockquote class="tr_bq" style="text-align: justify;">
<span style="font-family: "courier new" , "courier" , monospace;">..............</span></blockquote>
<blockquote class="tr_bq" style="text-align: justify;">
<span style="font-family: "courier new" , "courier" , monospace;">..... let s = DA.encode json</span> </blockquote>
<blockquote class="tr_bq" style="text-align: justify;">
<span style="font-family: "courier new" , "courier" , monospace;">.............</span> </blockquote>
<blockquote class="tr_bq" style="text-align: justify;">
which will make anyone reading the code to understand it easily as well.</blockquote>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<blockquote class="tr_bq">
These are some ways, I thought the best ways to solve the dependency problems in Haskell. In any case if you mistakenly unregister a package, you can always install it again by using </blockquote>
</div>
<div style="text-align: justify;">
<blockquote class="tr_bq">
<span style="font-family: "courier new" , "courier" , monospace;">'cabal install <packageName>'</span></blockquote>
</div>
<div style="text-align: justify;">
<br />
<ul>
<li>Solution to Backjump limit reached, which lead unresolved dependencies</li>
</ul>
<blockquote class="tr_bq">
A sample of this error, when installing packages in cabal is as follows;</blockquote>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/--GQ_bwxmnEY/VksHz6NZcUI/AAAAAAAAAmM/w6F6XxLtkxQ/s1600/dep_7.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="222" src="http://3.bp.blogspot.com/--GQ_bwxmnEY/VksHz6NZcUI/AAAAAAAAAmM/w6F6XxLtkxQ/s400/dep_7.PNG" width="400" /></a></div>
<blockquote class="tr_bq">
This error occurs when the dependency tree searched exhaustively. One way to solve this is to arrange the dependencies into an order, which will make it easier for the compiler resolve them. To do this we can use, </blockquote>
<blockquote class="tr_bq">
<span style="font-family: "courier new" , "courier" , monospace;">'cabal install <packageName> --reorder-goals'</span> </blockquote>
<blockquote class="tr_bq">
Another solution, as the compiler suggests is to change the <span style="font-family: "courier new" , "courier" , monospace;">'max-backjumps'</span><span style="font-family: inherit;"> from the default to a preferred value. </span></blockquote>
<br /></div>
<div style="text-align: justify;">
Hope this post helped you !! </div>
</div>
Dananji Withanahttp://www.blogger.com/profile/04345021233196010166noreply@blogger.com0Asia8.0592296272002173 80.859375-22.530071372799782 39.550781 38.648530627200216 122.167969tag:blogger.com,1999:blog-3488193442448451653.post-36654328473790825312015-07-21T22:09:00.004-07:002016-02-29T22:10:24.597-08:00RCON Client in Haskell<div dir="ltr" style="text-align: left;" trbidi="on">
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Source RCON is a TCP/IP based communication protocol, which can be used to issue console commands to the server via a remote console. The most common use of it, is to allow the server owners to control their game server properties without physically accessing the server. In order to use this, first one should be authenticated using the server's RCON password. </div>
<div style="text-align: justify;">
<br />
<u>Step 1: Setup the Minecraft server</u><br />
<u><br /></u></div>
<div style="text-align: justify;">
To start off with the developing the RCON client, you should first establish a server to test your client. For this I'm using Minecraft. You can download the Minecraft server <a href="https://minecraft.net/download" target="_blank">here</a>, and run it. When started it creates a file called 'server.properties' in your working directly and shuts down immediately. The first step of configuration is to open the file 'EULA.txt' ( do not use a rich text editor like Wordpad, use Notepad, Gedit, etc ), and change <span style="font-family: "courier new" , "courier" , monospace;">'eula=false'</span><span style="font-family: inherit;"> to </span><span style="font-family: "courier new" , "courier" , monospace;">'</span><span style="font-family: "courier new" , "courier" , monospace;">eula=true'</span><span style="font-family: inherit;">. </span><br />
<span style="font-family: inherit;"><br /></span>
<span style="font-family: inherit;">Then edit your 'server.properties' manually to say </span><span style="font-family: "courier new" , "courier" , monospace;">'enable-rcon=true'</span><span style="font-family: inherit;">. Then save it and run the server again. Then edit the 'server.properties' file again to add your </span><span style="font-family: "courier new" , "courier" , monospace;">'rcon.password'</span><span style="font-family: inherit;">. After these steps, your 'server.properties' file should look like this;</span><br />
<span style="font-family: inherit;"><br /></span>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-NtsJ7m1xtbM/VbCv_xcD-DI/AAAAAAAAAfs/zIE5FqDJDv0/s1600/rc_1.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="400" src="http://4.bp.blogspot.com/-NtsJ7m1xtbM/VbCv_xcD-DI/AAAAAAAAAfs/zIE5FqDJDv0/s400/rc_1.PNG" width="156" /></a></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
<u>Step 2: Establish a connection with the Minecraft server</u></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: justify;">
In order to start with the development, first you should establish a connection with the server. In this step we need to identify a way to build a simple connection over the network using sockets.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-iatPpDde8vk/VbC1pGKMNWI/AAAAAAAAAf8/4VZ9_62Ey2o/s1600/rc_2.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://4.bp.blogspot.com/-iatPpDde8vk/VbC1pGKMNWI/AAAAAAAAAf8/4VZ9_62Ey2o/s1600/rc_2.PNG" /></a></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: justify;">
Here 'Network.Socket' package is being used to create a connection with the server. First a socket is created using 'AF_INET' as the socket family, 'Stream' as the socket type, along with a default protocol. </div>
<div class="separator" style="clear: both; text-align: justify;">
When we run this code after starting the Minecraft server, if you have got it correct it prints a log entry in the log file indicating the connection as follows; </div>
<div class="separator" style="clear: both; text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-mBJxvkNAD-8/VbC6Em54akI/AAAAAAAAAgQ/AQ6mkpTEGTU/s1600/rc_3.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://1.bp.blogspot.com/-mBJxvkNAD-8/VbC6Em54akI/AAAAAAAAAgQ/AQ6mkpTEGTU/s1600/rc_3.PNG" /></a></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
<u>Step 3: Sending data over the network</u></div>
<div class="separator" style="clear: both; text-align: left;">
<u><br /></u></div>
<div class="separator" style="clear: both; text-align: left;">
Understanding the format of the data packets accepted by the server is a crucial part before sending data over the network. To understand this please go through the documentation at this <a href="https://developer.valvesoftware.com/wiki/Source_RCON_Protocol" target="_blank">page</a>. </div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
According to the documentation we can build a Haskell data constructor to send our data over the network as follows;</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-4GOi7lymFAk/VbC9_mAeo4I/AAAAAAAAAgc/w_KuMgV3NcY/s1600/rc_4.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://3.bp.blogspot.com/-4GOi7lymFAk/VbC9_mAeo4I/AAAAAAAAAgc/w_KuMgV3NcY/s1600/rc_4.PNG" /></a></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
First we need to build the data packet encapsulating the data we need to send over the network, and arrange them as a byte array to be sent over the network. In this code I have used 'Network.Socket.ByteString' send and receive data over the network. Since its 'send' method accepts a ByteString, the byte array needs to converted into a ByteString to feed into this method. </div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
Here the byte array representation of data in Haskell is a [Word8]. I've used 'Data.Bits' package to convert the Int values to [Word8] as follows;</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-E_y-PsaUJzA/VbDCVQ_CXXI/AAAAAAAAAgw/25TOe9kp-pM/s1600/rc_5.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://3.bp.blogspot.com/-E_y-PsaUJzA/VbDCVQ_CXXI/AAAAAAAAAgw/25TOe9kp-pM/s1600/rc_5.PNG" /></a></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
And then this array of Word8 elements is packed into a ByteString using the 'pack' method in 'Data.ByteString' package. </div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
The complete code can be found at my GitHub <a href="https://github.com/Dananji/RCONClient" target="_blank">repository</a>. </div>
</div>
</div>
Dananji Withanahttp://www.blogger.com/profile/04345021233196010166noreply@blogger.com2tag:blogger.com,1999:blog-3488193442448451653.post-19646818276945333852015-07-13T20:26:00.000-07:002016-02-29T22:10:24.591-08:00Develop a Mailchimp library with Haskell<div dir="ltr" style="text-align: left;" trbidi="on">
<div style="text-align: left;">
<div style="text-align: justify;">
<a href="http://mailchimp.com/" target="_blank">Mailchimp</a> is a free email marketing service provider. It helps you to design email newsletters, share them on social networks, integrate with services you already use and track your results. </div>
</div>
<div style="text-align: left;">
<div style="text-align: justify;">
<br /></div>
</div>
<div style="text-align: left;">
<div style="text-align: justify;">
Haskell is an advanced purely-functional programming language, which has improved performs than other imperative languages. </div>
</div>
<div style="text-align: left;">
<div style="text-align: justify;">
<br /></div>
</div>
<div style="text-align: left;">
<div style="text-align: justify;">
I have developed a library in Haskell interacting with the JSON API in Mailchimp, which enables one to do the following tasks with respect to a mailing list in Mailchimp;</div>
</div>
<div style="text-align: left;">
</div>
<ul style="text-align: left;">
<li style="text-align: justify;">Add subscribers</li>
<li style="text-align: justify;">List subscribers in a particular mailing list</li>
<li style="text-align: justify;">List mailing lists for a particular user account</li>
<li style="text-align: justify;">Past activities performed on a given mailing list</li>
</ul>
<div>
<div style="text-align: justify;">
Before starting off with the implementation, you should understand the functionalities we can perform on a mailing list in Mailchimp. For that, you should create a mailing list in Mailchimp. So, let's first go through the steps of creating a mailing list in Mailchimp (Here I'm referring to version 2.0 API)</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<u>Create a mailing list in Mailchimp</u></div>
<ul style="text-align: left;">
</ul>
<ol style="text-align: left;">
<li><span style="text-align: justify;">After creating an account in Mailchimp, first thing you have to do is the creation of an 'apikey', which provides the authentication purpose in the JSON API in Haskell</span></li>
<ul>
<li><div style="text-align: justify;">
Navigate to your 'Account'</div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-6MO-3Fd4YGc/VZtOeJqAS6I/AAAAAAAAAeE/A5Vf3c3baFQ/s1600/mc_1.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em; text-align: justify;"><img border="0" height="112" src="http://2.bp.blogspot.com/-6MO-3Fd4YGc/VZtOeJqAS6I/AAAAAAAAAeE/A5Vf3c3baFQ/s200/mc_1.png" width="200" /></a></div>
</li>
<li><div class="separator" style="clear: both; text-align: left;">
<a href="http://1.bp.blogspot.com/-MWZC-q-W2Tg/VZtPYWzHjkI/AAAAAAAAAeQ/Z8doDq0kjC4/s1600/mc_2.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em; text-align: justify;"><img border="0" height="73" src="http://1.bp.blogspot.com/-MWZC-q-W2Tg/VZtPYWzHjkI/AAAAAAAAAeQ/Z8doDq0kjC4/s200/mc_2.png" width="200" /></a></div>
<div style="text-align: justify;">
Then go to the 'API keys' from the drop down menu in 'Extras'</div>
<br />
</li>
<li><div class="" style="clear: both; text-align: left;">
<div style="text-align: justify;">
Then create an API key from the menu</div>
</div>
</li>
</ul>
<li><span style="text-align: justify;">Then create a mailing list according to your/client's preferences</span></li>
<li><span style="text-align: justify;">Then try adding couple of subscribers from the web interface and explore the functionalities available</span></li>
</ol>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<u>Implementation of library</u></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
After that I recommend you to read the Mailchimp API <a href="https://apidocs.mailchimp.com/api/2.0/" target="_blank">documentation</a>. This one is the Mailchimp version 2.0. Pay a closer attention towards the sample JSON requests and responses. </div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Then select the functionality you want in your library, and start coding. In my library I have selected the above mentioned functionalities.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
The first step of the implementation is the construction of the EndPoint URL, since all of the method descriptions in the API documentation are relative to it. The format of the end-point URL is as follows; `<span style="font-family: "courier new" , "courier" , monospace;">https://<dc>.api.mailchimp.com/2.0/SECTION/SOME_METHOD.OUTPUT_FORMAT</span>`, where `<span style="font-family: "courier new" , "courier" , monospace;"><dc></span>` refers to the data-center prefix. </div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
The data-center prefix is the last part of your apikey separated by the "-" character. In order to retrieve the end-point URL you need to extract it. Here is a snapshot of my implementation of it;</div>
<div style="text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-pKK2EAVgybA/VZuV7yyLxcI/AAAAAAAAAe0/vTrfb_WRdW0/s1600/mc_5.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://3.bp.blogspot.com/-pKK2EAVgybA/VZuV7yyLxcI/AAAAAAAAAe0/vTrfb_WRdW0/s1600/mc_5.PNG" /></a></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
One of the main sections, that you must pay attention is the exception handling in HTTP requests and responses. </div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
In my implementation I have used the `<span style="font-family: "courier new" , "courier" , monospace;">catch</span>` method imported from `<span style="font-family: "courier new" , "courier" , monospace;">Control.Exception</span>` package.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
As explained in the Hackage <a href="https://hackage.haskell.org/package/base-4.7.0.2/docs/Control-Exception.html" target="_blank">documentation</a> the statement which throws the exception is encapsulated within the catch statement, and then in the handler function the thrown `<span style="font-family: "courier new" , "courier" , monospace;">StatusCodeException</span>` is handled by calling the `<span style="font-family: "courier new" , "courier" , monospace;">getResponse</span>` function.</div>
<div style="text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-OL7aQ6Faz6g/VZuRU1Quk3I/AAAAAAAAAeg/_qaYrjSVAQY/s1600/mc_4.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://3.bp.blogspot.com/-OL7aQ6Faz6g/VZuRU1Quk3I/AAAAAAAAAeg/_qaYrjSVAQY/s1600/mc_4.PNG" /></a></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Here the `<span style="font-family: "courier new" , "courier" , monospace;">StatusCodeException</span>` has 3 parameters, they are; Status, ResponseHeaders, and CookieJar as explained in the Hackage <a href="https://hackage.haskell.org/package/http-client-0.2.1.1/docs/Network-HTTP-Client.html#t:HttpException" target="_blank">documentation</a>. </div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
These are then passed into `<span style="font-family: "courier new" , "courier" , monospace;">getResponse</span>` function. Using those 3 components it builds a Response of the same format as `<span style="font-family: "courier new" , "courier" , monospace;">withManager $ httpLbs req</span>`.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Here is the link to the GitHub <a href="https://github.com/Dananji/MailchimpSimple" target="_blank">repository</a> of my code, which is a work in progress. I hope to further develop it to support Mailchimp version 3.0 in the future. </div>
<blockquote class="tr_bq ">
</blockquote>
</div>
</div>
Dananji Withanahttp://www.blogger.com/profile/04345021233196010166noreply@blogger.com6tag:blogger.com,1999:blog-3488193442448451653.post-22104331491950069832015-06-03T01:58:00.000-07:002016-03-30T22:16:21.676-07:00Setting Up Snap with Haskell in Windows 8<div dir="ltr" style="text-align: left;" trbidi="on">
<div style="margin-bottom: 29px; text-align: left;">
<div style="line-height: 29px;">
<div style="text-align: justify;">
<div style="line-height: normal;">
<span style="line-height: 29px;">Snap is a Web development framework for Unix systems, written in Haskell programming language. Snap has a high level test coverage it well documented.</span></div>
<span style="line-height: 29px;">It is a;</span><br />
<ul>
<li>A fast HTTP server library</li>
<li>A sensible and clean monad for web programming</li>
<li>An HTML-based templating system for generating pages</li>
</ul>
<span style="line-height: 29px;">Here I'm going to explain how Snap can be used to develop web applications in Haskell in a Windows 8 environment.</span><br />
<span style="line-height: 29px;">This is done using Cabal, a system written for building and packaging Haskell libraries. </span>If you have not installed Haskell platform in your PC then please follow this link to download the platform. The installer will set up the Haskell environment once you run it and restart your PC.<br />
<span style="line-height: 29px;">To get on with the Snap open Command line and get the latest libraries in Cabal as follows;</span><br />
<div style="color: #0c1a30;">
<br /></div>
</div>
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-inauTXVD3jk/VVVcE_GeyTI/AAAAAAAAAWY/GSm4DdUA960/s1600/blog_1.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em; text-align: justify;"><span style="background-color: white; font-family: inherit;"><img border="0" height="48" src="https://2.bp.blogspot.com/-inauTXVD3jk/VVVcE_GeyTI/AAAAAAAAAWY/GSm4DdUA960/s640/blog_1.PNG" width="640" /></span></a></div>
<div style="text-align: justify;">
<span style="background-color: white; font-family: inherit;"><br /></span></div>
<span style="line-height: 29px; text-align: justify;">And then,</span><br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-YhcIz1V6dYM/VVVce0RI08I/AAAAAAAAAWg/dfFADUb2e7M/s1600/blog_2.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em; text-align: justify;"><span style="background-color: white; font-family: inherit;"><img border="0" height="43" src="https://4.bp.blogspot.com/-YhcIz1V6dYM/VVVce0RI08I/AAAAAAAAAWg/dfFADUb2e7M/s640/blog_2.PNG" width="640" /></span></a></div>
<div style="text-align: justify;">
<span style="background-color: white; font-family: inherit;"><br /></span></div>
<div style="text-align: justify;">
Snap installs in ~/.cabal/bin<br />
<br />
Restart your PC to add it to your path variable.<br />
<br />
Now you're ready to start using Snap. To set up Snap,create a project.<br />
<br /></div>
<div style="text-align: justify;">
<span style="background-color: white; font-family: inherit;"><br /></span></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-zuwFlA0BYEU/VVVeNPU4XuI/AAAAAAAAAWs/Z8tTQH0migI/s1600/blog_3.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em; text-align: justify;"><span style="background-color: white; font-family: inherit;"><img border="0" height="80" src="https://3.bp.blogspot.com/-zuwFlA0BYEU/VVVeNPU4XuI/AAAAAAAAAWs/Z8tTQH0migI/s640/blog_3.PNG" width="640" /></span></a></div>
<div style="text-align: justify;">
<span style="background-color: white; font-family: inherit;"><br /></span></div>
<div style="text-align: justify;">
The 'snap init barebones' sets up a simple HTTP framework, which you can work on. Now we have the following files in our project's folder;<br />
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-wCJH1z8oJxw/VVVpjVag9kI/AAAAAAAAAW8/DryZSPzcOaE/s1600/blog_4.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><span style="background-color: white; font-family: inherit;"><img border="0" height="108" src="https://4.bp.blogspot.com/-wCJH1z8oJxw/VVVpjVag9kI/AAAAAAAAAW8/DryZSPzcOaE/s640/blog_4.PNG" width="640" /></span></a></div>
<div style="text-align: justify;">
<span style="background-color: white; font-family: inherit;"><br /></span></div>
<div style="text-align: justify;">
To make the executable run the following command, which compiles our project and installs in ~/.cabal/bin.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://2.bp.blogspot.com/-Im7N4NPT5tM/VVVqaOEB4vI/AAAAAAAAAXE/08zUPaXnWGw/s1600/blog_5.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="22" src="https://2.bp.blogspot.com/-Im7N4NPT5tM/VVVqaOEB4vI/AAAAAAAAAXE/08zUPaXnWGw/s640/blog_5.PNG" width="640" /></a></div>
<br />
To start your web-server type the following command in the terminal;<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://1.bp.blogspot.com/-DffzASmtT7E/VVVq5ba_IOI/AAAAAAAAAXM/c8HqL6Iyh2c/s1600/blog_6.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="24" src="https://1.bp.blogspot.com/-DffzASmtT7E/VVVq5ba_IOI/AAAAAAAAAXM/c8HqL6Iyh2c/s640/blog_6.PNG" width="640" /></a></div>
<br />
Now you're running a webserver on port 8000. You can change the by changing the value at the end of the command - 'websiteSample -p 1255'<br />
<br />
Open up your web browser and go to 'localhost:8000' to see your website!<br />
<br />
See what happens when you visit the end points;<br />
http://localhost:8000/foo<br />
http://localhost:8000/echo/bar</div>
</div>
<ul class="compact" style="background-color: white; color: #0c1a30; font-family: georgia, serif; font-size: 16px; line-height: 29px; list-style: none; margin: 0px 0px 29px 10px; padding-left: 10px; text-indent: -13px;">
</ul>
</div>
Dananji Withanahttp://www.blogger.com/profile/04345021233196010166noreply@blogger.com0