0

I have the following problem: given a max(max) apacity, and given a list of values(listOfValues) i need to return a list with values from the listOfValues. The sum of the elements must be <= max and i need to prioritize the higher values.

Example: typing solvingProblem 103 [15, 20, 5, 45, 34] i must get: [45, 45, 5, 5]

To solve the problem i create the following code:

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

In the two lines where i'll returning "-1" should be the parameter "result", but if i change "-1" to "result" the code don't load on ghci.

Can someone help me?

Thank you and sorry for my bad english.

1
  • Always add type signatures for your functions. They make the code more readable and idiomatic, and most importantly allow GHC to check your functions indeed return what you intended to, often greatly improving the type error messages. Further, in the future, when asking on SO, if you receive an error from the compiler, post it! It contains valuable information for us, even if it might tell little to you. Commented Aug 5, 2016 at 8:37

2 Answers 2

3

If I may begin with a bit of a side note, some of your functions already exist in Haskell (now that I come to think of it you might have written them for an exercise, but just in case it wouldn't be the case, let's discuss that): your higher is maximum, your smaller is minimum and your insert is just (:), beacause like you write it yourself insert x list = x:list. Note that your version will fail if you give it the empty list because the pattern matching is non-exhaustive. Also you could write remove in terms of filter: remove x list = filter (== x) list.

Now why doesn't your code load properly? ghci tells you:

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

Which I agree is pretty cryptic, but what it's saying is that the return type of solvingProblem is a list of a and for some reason it is also an instance of the Num type class. The reason why it says it's an instance of Num is because one of the return value of solvingProblem is 0 which is a number, which is a bit odd because it is also a list. Changing the 0 with [] makes the code compile and work (if you change insert with (:) otherwise you get the non-exhaustive pattern matching I was talking about earlier).

λ> solvingProblem 103 [15,20, 5, 45, 34]
[5,5,45,45]
it :: (Ord t, Num t) => [t]
Sign up to request clarification or add additional context in comments.

11 Comments

Hi villou24. Thank you for the reply. I think I understand what you said, but i changed solvingProblem max [] = 0 solvingProblem max listOfValues | max == 0 = 0 to solvingProblem max [] = [] solvingProblem max listOfValues | max == 0 = [] and it don't compile
Have you changed the -1 with result? What is the error saying?
now i did (: . sorry for that. it compile now. the error now is Non-exhaustive patterns in function insert, probably semantics problem. I'll try to solve this now. Thank you very very much
and about the functions that already exists, some of the ones you quote i already knew and some not, but i can't use any of them in this project. but thank you anyway for that tip
No problem ;) Your non-exhaustive pattern matching is due to the fact that insert is not defined for empty lists, you can either add a case insert x [] = [x] or straight-away say insert = (:)
|
1

The problem is with the last guard clause in createList.

The type you intended for createList seems to be:

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

but if you look at the last guard clause you have:

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

Even though GHC is very good at inferring types, always adding type signatures to your code is a good way of catching these kinds of errors early.

3 Comments

Hi ErikR. Thank you for the reply. What i need to return in the end of all is a list of integers. typing solvingProblem 103 [15, 20, 5, 45, 34] for example i must get: [45, 45, 5, 5]
Add type signatures to all of your functions and I'll take another look at it.
In fact, after you add type signatures it might make the problem a lot more obvious.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.