My first Haskell Adventure !

Hi !

I’ve been trying to spend some time with Haskell for long but college.. assignments … etc..were keeping me away. Finally got time + kick + excitement last night and decided to code something meaningful.
Thought to solve this challenge one more time >

Its quite simple. Read from input.txt [which is actually a twitter feed] > remove duplicate id entries > sort in descending order of Timestamp and save to output.txt.

Took pretty long time though. I was also reading relevant pages from RWH. had to read some things like Monads twice/thrice to understand. Then talking to folks in IRC #Haskell.. Still have to go through alot.

but it was fun. yeah! my first Haskell program that works as expected ūüėÄ

here’s the code. It still requires alot of cleaning and will do that after posting this. but this is the final v1.0 that works. So wanted to share this one only ūüėÄ

-- to solve challenge program given here >
import System.IO
import List

main :: IO()
main = do 
    -- openFile returns a Handle
    inh <- openFile "pInput.txt" ReadMode
    -- get all the contents from input file
    inputData <- hGetContents inh
    -- get file contents split into array
    let pData = lines inputData
    -- store all lines in a list of Tweet data type
    let tweets = getTweets pData
    -- Remove duplicate entries
    -- nubBy function removes duplicate entries
    -- first argument is a 'comparer function'
    -- second argument is list on which it works
    let nDup = List.nubBy tweetEq tweets
    -- Sort in descending order of timestamp
    -- first argument is ordering function
    -- second argument is list to work on
    let sDup = List.sortBy tweetOrd nDup
    -- open file for writing. openFile returns a Handle
    outh <- openFile "pOutput.txt" WriteMode
    -- send Handle and data to write to file
    writeToFile outh sDup
    --close both Handles
    hClose inh
    hClose outh

    -- Custom data type to store a tweet
data Tweet = Tweet {
        tid :: Int,
        name :: String,
        time :: Double,
        message :: String

-- function that equates two Tweets
-- passed to nubBy
tweetEq :: Tweet -> Tweet -> Bool
tweetEq t1 t2 = (tid t1) == (tid t2)

-- function that checks order
-- passed to sortBy
tweetOrd :: Tweet -> Tweet -> Ordering
tweetOrd t1 t2 = compare (time t2) (time t1)

-- convert Tweet Lines into List of Tweets
getTweets :: [String] -> [Tweet]
getTweets [] = []
getTweets (x:xs) =  let parts =  split x '|' in
             let temp = Tweet{
                    tid = read (parts !! 0),
                    time = read (parts !! 1),
                    name = (parts !! 2),                    
                    message = (parts !! 3)
            in [temp] ++ (getTweets xs)

-- no comments :-P
split :: String -> Char -> [String]
split [] delim = [""]
split (c:cs) delim
   | c == delim = "" : rest
   | otherwise = (c : head rest) : tail rest
       rest = split cs delim

-- no comments
writeToFile :: Handle -> [Tweet] -> IO()
writeToFile outh [] =  hPutStrLn outh ""
writeToFile outh (x:xs) = do
              let line = (show(tid x)) ++ "|" ++ (show(time x)) ++ "|" ++ (name x) ++ "|" ++ (message x)
                      hPutStrLn outh line
              writeToFile outh xs

One comment

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s