2015-01-03 4 views
3

Мне нужно написать функцию в Haskell, которая суммирует элементы списка, пока некоторые определенные элементы не будут сохранены в другом списке.Haskell частичная сумма ошибки списка

Например, partial_add [1,2,3,4,5,6] [2,5] 0 должен вернуться [3,12,6].

Я достиг этого далеко:

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 

(скорее всего, не работает должным образом)

Но когда я пытаюсь запустить функцию (он компилирует правильно) я получаю эту ошибку:

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

Любая идея, что происходит?

+3

Подсказка: выражение 'partial_add x list count + a' интерпретируется как' (partial_add x list count) + a' not 'partial_add x list (count + a)'. – Rufflewind

+0

Hint2: Проверьте тип 'partial_add'. Затем попробуйте добавить правильную подпись типа самостоятельно. – Zeta

+0

Спасибо всем!Мне нужно было объявить тип partial_add :: [Int] -> [Int] -> Int -> [Int] и добавить круглую скобку вокруг count + a – Panos

ответ

2

Учитывая ваш пример, я хотел бы написать функцию что-то вроде этого:

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. Я думаю, что решение в вашем вопросе, кажется, не работает совсем так, как вы указали в вашем примере (или я неправильно что-то):

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] 

Но это легко исправить, чтобы работать на вашем примере:

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] 
+0

Спасибо @bmk, что он действительно не работал должным образом. Второй код, который вы опубликовали, - это то, что я сделал для окончательного решения. – Panos

1

Примечание: меня немного смущает параметр count, поскольку он игнорируется в одном из рекурсивных вызовов, где он всегда передается как 0. Это должно быть легко добавить его поведение, как только станет понятнее, что он делает.

Другой способ смотреть на это в первую отдельно второй список * в подсписков разграниченных (и в том числе) элементы первого списка, а затем найти суммы каждого подсписка:

-- | 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] 

дает

[3,12,6] 

Я думаю, что это хороший пример «снизу вверх» программирования в Haskell.

* Я изменил порядок аргументов в соответствии с порядком, используемым Data.List.Split.

+0

Передача счетчика как 0 - мой способ сбросить счетчик: P не знаю, есть ли лучший способ, но это только мой третий день, работающий над haskell, и меня немного повлиял пролог. Спасибо за ваш ответ – Panos

0

Спасибо за ваши ответы, я понял это. Мне нужно было объявить тип функции и поместить скобки там, где они должны быть. Код действительно не работал, как должен, но я исправил это.

Вот фиксированный код:

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) 

Это не может быть наилучшим, но это сработало для меня.

Смежные вопросы