Sunday, August 23, 2015

Handling Dependencies in Haskell



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.

This can be seen in couple of different ways, they are; 

  • Recursive dependencies
cabal: Error: some packages failed to install: snap-core-0.9.7.0 failed during the building phase. 
The exception was: ExitFailure 1
  • Hidden packages/modules
SnapUtil.hs:26:18:
    Could not find module ‘Safe’
    It is a member of the hidden package ‘safe-0.3.9’.
    Use -v to see a list of the files searched for.
  • Uncertainty of the package by which a particular module is being imported

 CMD.hs:19:17:
    Ambiguous occurrence ‘lookup’
    It could refer to either ‘CMD.lookup’, defined at                 CMD.hs:12:20 or ‘Prelude.lookup’,  
         imported from ‘Prelude’ at CMD.hs:3:8-10 (and              originally defined in ‘GHC.List’)

  • Could not resolve dependencies, Backjump limit reached
cabal: Could not resolve dependencies:
trying: snap-0.14.0.6 (user goal)
......................
......................
Backjump limit reached (change with --max-backjumps)

To solve them there are numerous ways. Here I'm going to share some methodologies I know to go around the above issues.
  • Solution to recursive dependencies
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;
It lists both System directory packages and User directory packages.

System directory packages
User directory packages

 If you can eye the repeating packages you can unregister them using;
'ghc-pkg unregister <packageName | packageName-version>'
  • Solution to shadowed packages/ modules
In case of a hidden package you can see in the package list in parenthesis as follows;

Here the packages 'monad-tf-0.1.0.2' and 'network-uri-2.6.0.3' are hidden. You can expose those packages using;
'ghc-pkg expose <packageName | packageName-version>'
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;
 'ghc-pkg describe <packageName>'
The result of that command for the 'http-client'

 Here, you can see the hidden modules and the exposed-modules from the package. 
  • Solution to uncertainty of package by which a particular module is being imported
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. 
Another way is to import the packages as follows;
 'import Data.Aeson as DA'
That way you can always import the methods from the respective package like this,
..............
..... let s = DA.encode json 
............. 
 which will make anyone reading the code to understand it easily as well.

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 
'cabal install <packageName>'

  • Solution to Backjump limit reached, which lead unresolved dependencies
A sample of this error, when installing packages in cabal is as follows;

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,
'cabal install <packageName> --reorder-goals' 
Another solution, as the compiler suggests is to change the 'max-backjumps' from the default to a preferred value. 

Hope this post helped you !!  

Tuesday, July 21, 2015

RCON Client in Haskell


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. 

Step 1: Setup the Minecraft server

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 here, 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 'eula=false' to 'eula=true'

Then edit your 'server.properties' manually to say 'enable-rcon=true'. Then save it and run the server again. Then edit the 'server.properties' file again to add your 'rcon.password'. After these steps, your 'server.properties' file should look like this;



Step 2: Establish a connection with the Minecraft server

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.



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.  
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; 


Step 3: Sending data over the network

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 page

According to the documentation we can build a Haskell data constructor to send our data over the network as follows;


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. 

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;


And then this array of Word8 elements is packed into a ByteString using the 'pack' method in 'Data.ByteString' package. 

The complete code can be found at my GitHub repository

Monday, July 13, 2015

Develop a Mailchimp library with Haskell

Mailchimp 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. 

Haskell is an advanced purely-functional programming language, which has improved performs than other imperative languages. 

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;
  • Add subscribers
  • List subscribers in a particular mailing list
  • List mailing lists for a particular user account
  • Past activities performed on a given mailing list
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)

Create a mailing list in Mailchimp
  1. 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
    • Navigate to your 'Account'
    • Then go to the 'API keys' from the drop down menu in 'Extras'

    • Then create an API key from the menu
  2. Then create a mailing list according to your/client's preferences
  3. Then try adding couple of subscribers from the web interface and explore the functionalities available

Implementation of library

After that I recommend you to read the Mailchimp API documentation. This one is the Mailchimp version 2.0. Pay a closer attention towards the sample JSON requests and responses. 

Then select the functionality you want in your library, and start coding. In my library I have selected the above mentioned functionalities.

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; `https://<dc>.api.mailchimp.com/2.0/SECTION/SOME_METHOD.OUTPUT_FORMAT`, where `<dc>` refers to the data-center prefix. 

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;



One of the main sections, that you must pay attention is the exception handling in HTTP requests and responses. 

In my implementation I have used the `catch` method imported from `Control.Exception` package.

As explained in the Hackage documentation the statement which throws the exception is encapsulated within the catch statement, and then in the handler function the thrown `StatusCodeException` is handled by calling the `getResponse` function.



Here the `StatusCodeException` has 3 parameters, they are; Status, ResponseHeaders, and CookieJar as explained in the Hackage documentation.  

These are then passed into `getResponse` function. Using those 3 components it builds a Response of the same format as `withManager $ httpLbs req`.

Here is the link to the GitHub repository of my code, which is a work in progress. I hope to further develop it to support Mailchimp version 3.0 in the future. 

Wednesday, June 3, 2015

Setting Up Snap with Haskell in Windows 8

Snap is a Web development framework for Unix systems, written in Haskell programming language. Snap has a high level test coverage it well documented.
It is a;
  • A fast HTTP server library
  • A sensible and clean monad for web programming
  • An HTML-based templating system for generating pages
Here I'm going to explain how Snap can be used to develop web applications in Haskell in a Windows 8 environment.
This is done using Cabal, a system written for building and packaging Haskell libraries. 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.
To get on with the Snap open Command line and get the latest libraries in Cabal as follows;


And then,


Snap installs in ~/.cabal/bin

Restart your PC to add it to your path variable.

Now you're ready to start using Snap. To set up Snap,create a project.



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;


To make the executable run the following command, which compiles our project and installs in ~/.cabal/bin.


To start your web-server type the following command in the terminal;


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'

Open up your web browser and go to 'localhost:8000' to see your website!

See what happens when you visit the end points;
        http://localhost:8000/foo
        http://localhost:8000/echo/bar