this is an exercice :
-- Implement the function sumRights which sums all Right and discard Left
-- Examples:
-- sumRights [Right 1, Left "bad value", Right 2] ==> 3
-- sumRights [Left "bad!", Left "missing"] ==> 0
My idea was, as a first step, to transform the list with map into a list of integers only. I wrote the following :
transformListToInt :: [Either a Int] -> Int
transformListToInt list = map f list
where f (Right b) = b
f (Left c) = 0
But it gives me the following error :
* Couldn't match expected type `Int' with actual type `[a]'
* In the expression: map f list
In an equation for `sumRights':
sumRights list
= map f list
where
f (Right b) = b
f (Left c) = c
Could someone help me to understand why I get this error ? (the initial problem is not so important, I could solve it differently)
CodePudding user response:
You forgot to sum the list in the end:
transformListToInt :: [Either a Int] -> Int
transformListToInt list = sum $ map f list
where f (Right b) = b
f (Left c) = 0
A shorter way to write the same would be:
transformListToInt = sum . map (fromRight 0)
or even shorter:
transformListToInt = sum . rights
(both ways require importing Data.Either
)
CodePudding user response:
map
turns a list [x0,x1,...]
into another list [f x0, f x1, ...]
. It can not produce an Int
as your type claims, so the compiler complains.
Since your map
generates a value of type [Int]
, you need to transform that list into the sum of its elements (use sum
).