Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cubesumming in haskell

Tags:

haskell

Haskell has the sum function

sum :: Num a => [a] -> a

Which can be nicely composed to sum a matrix by

sum . map sum :: Num a => [[a]] -> a

Going deeper, however, such as summing a cube, creates the restriction Num [a]

sum . map sum . map sum :: (Num a, Num [a]) => [[[a]]] -> a

Which, if you think about it, is natural. So with the former attempt to define the sumcube function blowing up in one's face, we need to find a different path. One such attempt would be:

sum . map sum . map (map sum) :: Num a => [[[a]]] -> a

Which seems nowhere as natural as the summatrix function.

In my quest to posessing the mental tools for problem solving in Haskell, I am interested in knowing how to tackle this problem of summing a structure of any depth by, say, stacking map sums as in my third code example. Is this at all possible? And in that case, how would you do it?

like image 992
Magnus Kronqvist Avatar asked Dec 21 '11 17:12

Magnus Kronqvist


3 Answers

How about typeclasses?

class Summable a where
  total :: a -> Int

instance Summable Int where
  total = id  

instance Summable x => Summable [x] where
  total = sum . map total  

total ([[[1,2,3],[4,5]],[[6],[7,8,9,10]]] :: [[[Int]]])
--55
like image 130
Landei Avatar answered Oct 22 '22 09:10

Landei


You'll have to work from the inside out. When you have a function f for summing a data structure, then sum . map f is the way to sum a list of those data structures.

                     sum  :: Num a =>   [a]   -> a
           sum . map sum  :: Num a =>  [[a]]  -> a
sum . map (sum . map sum) :: Num a => [[[a]]] -> a
like image 32
Sjoerd Visscher Avatar answered Oct 22 '22 07:10

Sjoerd Visscher


Maybe this? Assumes associativity, but adding new layer is simple

 sum . concat . concat :: Num c => [[[c]]] -> c
like image 5
sdcvvc Avatar answered Oct 22 '22 07:10

sdcvvc