Cubesumming in haskell

Haskell has a sum function

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

What can be nicely composed to summarize the matrix on

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

However, deepening, for example, with the summation of the cube, the restriction Num [a] is created

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

What if you think about it, naturally. Thus, with the previous attempt to define the sumcube function, inflated on one face, we need to find another way. One such attempt:

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

It seems nowhere more natural than the summation function.

In my quest for using mental tools to solve problems in Haskell, I’m interested in learning how to solve this problem of summing up structures of any depth, say stacking a map sum , as in my third code example. Is it even possible? And in that case, how would you do that?

+8
haskell
source share
5 answers

You will have to work from the inside out. When you have a function f to summarize a data structure, then sum . map f sum . map f is a way to summarize a list of these data structures.

  sum :: Num a => [a] -> a sum . map sum :: Num a => [[a]] -> a sum . map (sum . map sum) :: Num a => [[[a]]] -> a 
+12
source share

What about styles?

 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 
+14
source share

Maybe this? Associativity is assumed, but adding a new layer is simple

  sum . concat . concat :: Num c => [[[c]]] -> c 
+5
source share

It seems to me most natural to define an additional dimension sum in terms of the previous dimension sum .

 -- given sum :: Num a => [a] -> a sum2 :: [[a]] -> a sum2 = sum . map sum sum3 :: [[[a]]] -> a sum3 = sum . map sum2 sum4 :: [[[[a]]]] -> a sum4 = sum . map sum3 

This is basically the same idea as Sjord. If you want to use only map and sum , rather than refactoring common subexpressions into usable names ... then use equational reasoning to replace custom functions sum2 , sum3 , etc.

+1
source share

First, the Haskell Template (a GHC extension, though). Or you can use data , which supports arbitrary deep nested enumeration:

 data Tree a = Leaf a | Node [Tree a] sumTree (Leaf x) = x sumTree (Node xs) = (sum . map sumTree) xs main = print $ sumTree $ Node [ Node [Leaf 3, Leaf 4, Leaf 5] , Node [Leaf 1, Leaf 4, Leaf 2]] 

19 will be printed here. However, this does not guarantee that all leaves have the same nesting depth, and I do not know how to do this from lists.

0
source share

All Articles