Reputation:
I have a list of char and integer like [('1',1),('2',2),('3',3),('4',4),('5',5)]
and want to turn the integers into the percentage each number count for the total such as [('1',7),('2',13),('3',20),('4',27),('5',33)]
. I have tried a recursive function which takes a parameter as (c,i):rest
and then divide the i
by the total and then call the function with rest
. But after every single loop, the total has changed. So is there any way I declare the total from start and use it over and over like other languages.
Upvotes: 1
Views: 122
Reputation: 15959
You need to calculate the total in advance - you can use something like
f :: Integral b => [(a,b)] -> [(a,b)]
f lst = let total = sum $ map snd list
in map (\(x,y) -> (x,(100 * y)`div` total)) lst
Note: it would be a good idea to collect the Integral
-values associated to each character beforehand, this makes the output a bit more clear (in my opinion), but this would be an exercise for the astute reader.
To make this function more clear - I would also recommend introducing newtypes
for Value
and Percentage
such that you never try to add values with percentages.
newtype Value a = V {extractV :: a}
newtype Percentage = P {percent :: Integer}
f :: Integral b => [(a,Value b)] -> [(a,Percentage)]
Upvotes: 2