In this short tutorial, I’m going to write a simple Haskell program to calculate the density of characters in a given text. For instance, in “hello” we have [('e',0.2),('h',0.2),('l',0.4),('o',0.2)].

The return format of our application would be a list of tuples

String -> [(Char, Float)]

To make the problem easier to solve, I’m going to break it into two programs. One that returns the number of repeats for each character and another program that converts that list to a percentage of repeats.

Count of repeats

freq_letter :: String -> [(Char, Int)]
freq_letter str = [ (x,c) | x <- ['a'..'z'], let c = (length.filter (==x)) str, c>0 ]

This program returns a list of tuples with the Char and Int. First item of tuple is the character in the given text and the second parameter, Int, is the count of repeats in the text. Executing this program will return:

*Main> freq_letter "hello"
[('e',1),('h',1),('l',2),('o',1)]

Percentage of repeats

freq_letter_pc :: String -> [(Char, Float)]
freq_letter_pc str = [ (char, fromIntegral(count) / fromIntegral(length str)) | x <- freq_letter (map toLower str), let (char,count) = x]

Second part of the application uses the previous program to get the list of repeats and then divide them by the length of the given text. This way we can calculate the density of characters in the text. Executing this program returns:

*Main> freq_letter_pc "hello"
[('e',0.2),('h',0.2),('l',0.4),('o',0.2)]

That’s it.

Conclusion

In this tutorial, we have learnt how to calculate the density of characters using Haskell. Achieving this goal is much easier in Haskell because of list comprehension and higher order functions.