2964349
2964349

Reputation: 165

counting no of times each word is repeated using haskell

iam new to Haskell and functional programing...

i want to pass in the function as a string and count no of times each syntax such as (if,else, elseif for, while, dowhile) is exist in the function using haskell.

example if give an input like this

if(i=0){  for(i=0;i<num;i++){if(name== name)}
}elseif (i=3){for(i=3;i<num;i++){}}
else{while (i>3){name = name; i--;}}

i expect the output.(it has to give no of times each syntax appear)

[(if,2),(for,2),(elseif,1),(else,1),(while,1)]

i had done the coding. as shown below

import Control.Arrow

syntaxCount :: String -> [(String, Int)]
syntaxCount = map (head &&& length) . group .sort  . words

this function works but it displays the result like this.

[("(i=3){for(i=3;i<num;i++){}}",1),("(i>3){name",1),("=",1),("else{while",1),("for(i=0;i<num;i++){if(name==",1),("i--;}}",1),("if(i=0){",1),("name)}",1),("name;",1),("}elseif",1)]

can anyone help me to get rid of all the unwanted stuff and get the result like this..

[(if,2),(for,12),(elseif,1),(else,1),(while,1)]

Upvotes: 2

Views: 393

Answers (1)

Chris Taylor
Chris Taylor

Reputation: 47392

I'd split this into a function that produces a list of the keywords in the input string, and a function that counts distinct elements of a list

import Data.Char
import Control.Arrow

keywords :: String -> [String]
keywords = words . map (\x -> if isAlpha x then x else ' ')

count :: Ord k => [k] -> [(k,Int)]
count = map (head &&& length) . group . sort

Then you can define syntaxCount as a simple composition

syntaxCount = count . keywords

For example

>> let inp = "if(i=0){  for(i=0;i<num;i++){if(name== name)}\n}elseif (i=3){for(i=3;i<num;i++){}}\nelse{while (i>3){name = name; i--;}}"
>> syntaxCount inp
[("else",1),("elseif",1),("for",2),("i",10),("if",2),("name",4),("num",2),("while",1)]

If you want to include just a specific set of keywords, then you should filter explicitly for them

import qualified Data.Set as Set

allKeywords :: Set.Set String
allKeywords = Set.fromList ["if", "else", "elseif", "for", "while"]

keywords = filter (`Set.member` allKeywords) . words . map removePunc
  where removePunc c = if isAlpha c then c else ' '

Upvotes: 5

Related Questions