2016-08-05 2 views
0

У меня есть следующая проблема: учитывая max (max) apacity и заданный список значений (listOfValues), мне нужно вернуть список со значениями из listOfValues. Сумма элементов должна быть < = max, и мне нужно определить приоритеты более высоких значений.Ошибка при попытке «распечатать» список в Haskell

Пример: набрав solvingProblem 103 [15, 20, 5, 45, 34] я должен получить: [45, 45, 5, 5]

Для того, чтобы решить эту проблему я создать следующий код:

solvingProblem max [] = 0 
solvingProblem max listOfValues | max == 0 = 0 
           | otherwise = createList max listOfValues [] 


createList max [] result = -1 
createList max listOfValues result | smaller listOfValues > max = -1 
           | higher listOfValues > max = createList max (remove (higher listOfValues) listOfValues) result 
           | otherwise = createList (max - higher listOfValues) listOfValues (insert (higher listOfValues) result) 

higher [a] = a 
higher (a:b:x) | a > b = higher (a:x) 
       | otherwise = higher (b:x) 

smaller [a] = a 
smaller (a:b:x) | a < b = smaller (a:x) 
       | otherwise = smaller (b:x) 

remove x [] = [] 
remove x (h:t) | x == h = remove x t 
       | otherwise = h : remove x t 

insert x (h:t) = x : h : t 

В двух строках, где я возвращаю «-1», должен быть параметр «результат», но если я изменил «-1» на «результат», код не загружается на ghci.

Может кто-нибудь мне помочь?

Спасибо и извините за мой плохой английский.

+0

Всегда добавляйте сигнатуры типов для своих функций. Они делают код более читабельным и идиоматичным, и, самое главное, позволяют GHC проверять ваши функции, действительно возвращать то, что вы намеревались, часто значительно улучшая сообщения об ошибках типа. Кроме того, в будущем, когда вы спрашиваете о SO, если вы получаете сообщение об ошибке от компилятора, опубликуйте его!Он содержит ценную информацию для нас, даже если это может вам мало что сказать. – chi

ответ

3

Если я могу начать с небольшого примечания, некоторые из ваших функций уже существуют в Haskell (теперь, когда я придумаю это, вы могли бы написать их для упражнения, но на всякий случай это не будет в этом случае, давайте обсудим это): ваш higher - maximum, ваш smaller - minimum, а ваша вставка - только (:), beacause, как вы сами пишете insert x list = x:list. Обратите внимание, что ваша версия не удастся, если вы дадите ей пустой список, потому что соответствие шаблонов не является исчерпывающим. Также вы можете написать remove с точки зрения фильтра: remove x list = filter (== x) list.

Теперь почему ваш код не загружается должным образом? ghci говорит вам:

• Non type-variable argument in the constraint: Num [a] 
    (Use FlexibleContexts to permit this) 
• When checking the inferred type 
    solvingProblem :: forall a. 
         (Ord a, Num [a], Num a) => 
         a -> [a] -> [a] 

Что я согласен довольно загадочно, но то, что он говорит, что тип возвращаемого solvingProblem список a и по какой-то причине он также является экземпляром класса Num типа. Причина, по которой он говорит, что это экземпляр Num, объясняется тем, что одно из возвращаемых значений solvingProblem - это 0, что является немногочисленным числом, поскольку оно также является списком. Изменение 0 с помощью [] делает компиляцию кода и работу (если вы меняете insert с (:), иначе вы получите не исчерпывающий образец соответствия, о котором я говорил ранее).

λ> solvingProblem 103 [15,20, 5, 45, 34] 
[5,5,45,45] 
it :: (Ord t, Num t) => [t] 
+0

Hi villou24. Спасибо за ваш ответ. Я думаю, что понимаю, что вы сказали, но я изменил solveProblem max [] = 0 solveProblem max listOfValues ​​| max == 0 = 0 до solveProblem max [] = [] solveProblem max listOfValues ​​| max == 0 = [] и он не компилируется –

+0

Вы изменили '-1' на' result'? Что такое ошибка? – villou24

+0

теперь я сделал (:. Извините за это, теперь он компилируется. Ошибка теперь - это не исчерпывающие шаблоны в функции insert, вероятно, проблема семантики. Я постараюсь решить это сейчас. Большое спасибо –

1

Проблема связана с последним пунктом охраны в createList.

Типа вы предназначены для createList, кажется:

createList :: Int -> [Int] -> Int -> Int 

, но если вы посмотрите на последнюю фразу охранника у вас есть:

| otherwise = createList (max - ...) listOfValues (insert ...) 
         ^^^^^^^^^^^ ^^^^^^^^^^^^ ^^^^^^^^^^^^ 
          Int  [Int]  [Int] 

Даже если GHC очень хорошо выводя типов, всегда добавляя подписи типа к вашему коду - хороший способ поймать эти виды ошибок на раннем этапе.

+0

Hi ErikR. Спасибо за ваш ответ. То, что мне нужно вернуть в конце всего, - это список целых чисел. Набрав решение проблемы 103 [15, 20, 5, 45, 34], например, я должен получить: [45, 45, 5, 5] –

+1

Добавьте подписи к всем вашим функциям, и я еще раз посмотрю на это. – ErikR

+1

Фактически, после добавления сигнатур типов это может сделать проблему намного более очевидной. – ErikR

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