2016-01-15 2 views
0

Я новичок в функциональном программировании и haskell, поэтому я только начинаю учиться, пытаясь решить проблемы Эйлера. Это связано с большим количеством суммирования списков.Суммарное суммирование рекурсивного списка Haskell

Так что я пытаюсь написать рекурсивный список функцию суммирования, которая принимает один список в качестве входных данных и возвращает целое число в качестве вывода, например:

-- Sum up a list 
listsum :: [int] -> int 
listsum [a:b:[]] = a + b 
listsum x = head x + listsum tail x 

При компиляции этого кода, я получаю эту ошибку:

Couldn't match expected type `[[int] -> int]' 
      with actual type `[a0] -> [a0]' 
Relevant bindings include 
    x :: [int] 
    (bound at C:\Users\Rade\Documents\GitHub\haskell\euler_2.hs:15:9) 
    listsum :: [int] -> int 
    (bound at C:\Users\Rade\Documents\GitHub\haskell\euler_2.hs:14:1) 
Probable cause: `tail' is applied to too few arguments 
In the first argument of `listsum', namely `tail' 
In the second argument of `(+)', namely `listsum tail x' 

Я попытался исследовать соответствие шаблонов, но я не могу понять, что это означает с ожидаемым типом по сравнению с фактическим типом. Где я иду не так?

ответ

4
listsum [a:b:[]] = a + b 

Здесь a:b:[] означает список [a, b], так [a:b:[]] означает [[a, b]], который не то, что вы хотите.

Просто измените это

listsum (a:b:[]) = a + b 

Сейчас в

listsum x = head x + listsum tail x 

часть listsum tail x средства применяются listsum к tail, а затем применить результат к x. Я полагаю, вы имели в виду применить tail до x, а затем применить listsum к результату, что может быть выражено как listsum (tail x).


Я предлагаю немного более чистую реализацию, которая предполагает, что суммирование пустого списка дает нуль.

listsum [] = 0 
listsum (x:t) = x + listsum t 

Это отличается функциональностью от вашей реализации, поскольку она правильно обрабатывает списки с нулем или одним элементом.

+0

Вы были прав насчет проблемы [a: b: []], но я все равно получаю ту же ошибку. Кроме того, ваша чистая реализация компилируется, но это одно и то же? Разве 1 ​​не будет интерпретироваться как значение 1, а не некоторый список какого-то размера? – Hawkins

+0

@Rade Я нашел еще одну проблему с вашей реализацией; Я скоро обновлю ответ. – lisyarus

+1

@Rade, кстати, это не «1», это маленькая буква «L». Я изменил его, чтобы предотвратить дальнейшую путаницу. – lisyarus

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