Partial sum of Haskell list error

I need to write a function in Haskell that sums the elements of a list until some specific elements are stored in another list.

For example partial_add [1,2,3,4,5,6] [2,5] 0

should return [3,12,6]

.

I got to this:

partial_add [] _ count = []
partial_add (a:x) list count | elem a list =  count:partial_add x list 0
                             | otherwise =  partial_add x list count+a

      

(most likely not working as expected)

But when I try to run the function (it compiles correctly) I get this error:

No instance for (Num [t0]) arising from a use of `it' 
In a stmt of an interactive GHCi command: print it

      

Any idea what's going on?

+3


source to share


3 answers


Given your example, I would write a function something like this:

partialAdd :: [Int] -> [Int] -> [Int]
partialAdd ls seps = foldr f [] ls
  where 
    f a [] = [a]
    f a (x:xs)
      | a `elem` seps = a:x:xs
      | otherwise = (x+a):xs

*Main> partialAdd [1,2,3,4,5,6] [2,5]
[3,12,6]

      

Btw. I think the solution in your question doesn't seem to work the way you pointed out in your example (or I misunderstood something):



partial_add :: [Int] -> [Int] -> Int -> [Int]
partial_add [] _ count = []
partial_add (a:x) list count | elem a list =  count:partial_add x list 0
                             | otherwise =  partial_add x list (count+a)

*Main> partial_add [1,2,3,4,5,6] [2,5] 0
[1,7]

      

But it's easy for your example to work:

partial_add :: [Int] -> [Int] -> Int -> [Int]
partial_add [] _ count = [count]
partial_add (a:x) list count | elem a list =  (count+a):partial_add x list 0
                             | otherwise =  partial_add x list (count+a)

*Main> partial_add [1,2,3,4,5,6] [2,5] 0
[3,12,6]

      

+2


source


Note. I am a bit confused about the parameter count

as it is ignored in one of the recursive calls where it is always passed as 0

. It should be easy to add his behavior when it becomes clearer what he does.

Another way to look at this is to first separate the second list * in the sublists, separated by (and including) the elements of the first list, and then find the sums of each sublist:

-- | A version of Data.List.splitOneOf that includes the delimiter
splitOneOf' :: Eq a => [a] -> [a] -> [[a]]
splitOneOf' _ [] = [[]]
splitOneOf' delims (x:xs) | x `elem` delims = [x] : splitOneOf' delims xs
splitOneOf' delims (x:xs) | otherwise = let (ys:yss) = splitOneOf' delims xs
                                        in (x:ys) : yss

partialAdd :: (Eq a, Num a) => [a] -> [a] -> [a]
partialAdd delims = map sum . splitOneOf' delims

main :: IO ()
main = print $ partialAdd [2,5] [1,2,3,4,5,6]

      

gives



[3,12,6]

      

I think this is a good example of bottom-up programming in Haskell.

* I changed the order of the argument to match the order used Data.List.Split

.

+1


source


Thanks for your answers, I figured it out. I needed to declare the type of the function and put the brackets where they should be. The code didn't really work as it should, but I fixed it.

Here's the fixed code:

partial_add :: [Int] -> [Int] -> Int -> [Int]        
partial_add [] _ count = [count]
partial_add (a:x) list count | elem a list =  (count+a):partial_add x list 0
                             | otherwise =  partial_add x list (count+a)

      

It may not be the best, but it worked for me.

0


source







All Articles