Adding the elements of a list of list in haskell (not concatenation but addition)

877 Views Asked by At

This is the program I have written to add a list of list of elements which may contain either a float or an integer. Doesn't seem to work at all and my lecturer is as clueless about this as I am and I cant find an appropriate solution for this, have tried list comprehension however most of the examples use direct inputs to the GHC not IO() programs. Also trying to use HOF(higher order functions) as evident by the function "summ".

    conc :: Num a => [[a]] -> [a]
    conc [] = []
    conc xss = [x | xs <- xss , x <- xs]

    summ :: ([[a]] -> [a]) -> [[a]] ->[a]
    summ [[f]] [[s]] = f (s)
    summ (h : t) = h + summ t

    summer :: IO()

    summer = do 
                putStr "Enter a List of List (Int/Float): "
                li <- getLine
                let li = (read li) :: [[Float]]

                let r = summ (conc li)

                putStrLn "Sum of the list of lists is: " ++ r
3

There are 3 best solutions below

0
On BEST ANSWER

So i solved my own question for those stuck with the same problem here is the solution.

conc::[[Int]]->[Int] -- taking a list-of-list as an argument and returning only a list.
conc [] = [] -- base case
conc (h:t) = h ++ conc t -- written to concatenate the list of lists.


summ::[Int]->Int
summ[]=0
summ (h:t) = h + summ t -- to sum up the elements of the list of list

summer1::([Int]->Int)->([[Int]]->[Int])->[[Int]]->Int -- A higher order function   
summer1 a b l = summ(conc l)                          

summer::IO()
summer = do
           putStr "Enter a list of list of integers: "
           x <- getLine
           let y = (read x) :: [[Int]]

           let sol = summer1 summ conc (y) -- takes the HOF and then applies to y 
           putStrLn ("The sum of the elements of the list of list is: " ++ show sol) --displaying the result
0
On

You might try

conc = map sum

to get the signature Num a => [[a]] -> [a] that you're looking for with a (+) operation between elements.

In addition, summ has a horrid type signature and will give you all sorts of errors. You probably just meant sum since you call it on the output of conc.

So for example this "just works":

main = do 
    putStrLn "Enter a list of lists of floats: "
    floats <- readLn :: IO [[Float]]
    putStrLn $ "Sum of the list of lists is: " ++ show (sum $ map sum $ floats)

(Here a $ b = a b, the $ sign is a function which helps to eliminate parentheses by being very low-precedence and right-associative; it basically says for example "putStrLn of the rest of this expression".)

0
On

Your summ function is very wrong. For one thing, you don't specify all the arguments to summ on the second line of its definition, but the real problem comes from the pattern matching in summ [[f]] [[s]]. You've told the compiler that summ has type ([[a]] -> [a]) -> [[a]] -> [a], which means that the first argument to summ must be a function, but the pattern [[f]] is a list containing a list containing a single element called f. This is also true for the pattern [[s]], that does not match any list, only a list like [[1]] or [[10]], it wouldn't match [], [[1, 2, 3]], [[1],[2],[]], or any other value for a nested list. If you were to change this to

summ f s = f s

Then this function would be nothing more than id for functions. Instead, if you want to get the sum of each list inside a list, you could simply use

summ l = map sum l

If you wanted instead to concatenate a list of lists of numbers into just a list of numbers, you should use the built-in concat function.

In summer, you also have summ (conc li), which would be incorrect for a higher order function, you should instead have summ conc li, where conc and li are both arguments to summ. However, I don't think you need this at all. Finally, in

putStrLn "Sum of the list of lists is: " ++ r

won't compile for 2 reasons: 1. this is parsed by the compiler as

(putStrLn "Sum of the list of lists is: ") ++ r

and 2. you can't concatenate a value on an IO (). If you used parentheses correctly as

putStrLn ("Sum of the list of lists is: " ++ r)

this wouldn't work because ++ requires both values to be of the same type, meaning you can only concatenate a String with another String. To convert values to String, you can use the show function, so it would look like

putStrLn ("Sum of the list of lists is: " ++ show r)