2016-06-08 3 views
-2
myfunc:: [Int] -> Int -> Int 
myfunc mylist i = 
    if length(mylist) == 0 then 1 

    else 
     (head(mylist) * i) + myfunc((tail(mylist)) (i+1)) 

Я хочу получить взвешенную сумму по списку.Haskell multiple arguments function

, например, при заданном значении параметра [10,9,8,7,6] и 1, Я хочу, чтобы получить 10*1 + 9*2 + 8*3 + 7*4 + 6*5 ..

Но мой код помещает ошибки,

test.hs:9:18: error: 
    • Couldn't match expected type ‘Int’ with actual type ‘Int -> Int’ 

, как решить эту проблему ??

+2

есть много * круглых скобок *: 'myfunc ((tail (mylist)) (i + 1))' - try 'myfunc (tail mylist) (i + 1)' (вы вызываете 'tail (mylist)' ' с '(i + 1)') – Carsten

+0

Вызов функций в Haskell не требует скобок. 'function first_argument' достаточно. Несколько аргументов передаются как 'function first_argument second_argument third_argument', что является таким же, как' ((function first_argument) second_argument) third_argument'. Функция с типом 'a -> b -> c' на самом деле является функцией с типом' a -> (b -> c) ': она принимает один аргумент (как и все функции Haskell) и возвращает другую функцию. –

+0

Вы, кажется, программируете в Haskell, как и на языке * обязательного * программирования. Mind Haskell - это * функциональный * язык программирования. Поэтому вы должны программировать * функционально *. Ваш текущий код очень * un * -Haskell. –

ответ

2

вы должны проверить круглые скобки - использовать их гораздо больше, то вам нужно (что приводит к проблеме здесь)

Если вы посмотрите на myfunc((tail(mylist)) (i+1)) тогда, если считать (..) вы увидите, что один аргумент myfunc здесь tail(mylist) (i+1), но это будет означать, что вы пытаетесь применить (i+1) к tail(mylist)

Кроме того, вместо проверки с length и head вы можете использовать шаблон-согласование.

вот очищен версия вашей функции:

myfunc :: [Int] -> Int -> Int 
myfunc [] _ = 1 
myfunc (h:tl) i = h*i + myfunc tl (i+1) 

который будет возвращать 111 для примера:

> myfunc [10,9,8,7,6] 1 
111 

Я не знаю, сколько вы видели of Haskell, но вы можете выразить это как

myfunc :: [Int] -> Int -> Int 
myfunc weights start = 1 + sum (zipWith (*) weights [start..]) 

тоже - что я хотел бы рассмотреть более читаемым и идиоматических

также: - почему 1 если список пуст? Должен ли ваш взвешенный сумма быть 0, если список пуст? ??

+0

Благодарим вас за ответ. Этот код является всего лишь прототипом моего задания. Я переписываю свой рекомендованный код, но возникла одна проблема. что я должен выполнять, выполняйте функцию в конкретной ситуации? например, myfunc (h: tl) = если проверить h ++ tl == True, то somthing. как этот код стиля будет переписан? Я хочу удалить заявление «если». –

+0

Первый 'h ++ tl', вероятно, не тот, который вы хотите (это' h: tl') - и это зависит от того, что действительно делает проверка (действительно ли нужны остальные списки или только 'h'?). - пожалуйста, откройте еще один вопрос, где вы описываете свою реальную проблему/эту проблему – Carsten