Haskell find divisors based on comprehension method

Viewed 58

I need a little help understanding a comprehension method function.

compdivides :: Integer -> [Integer]
compdivides x
    | x > 0 = [a | a <-[1..div x 2], mod x a == 0] ++ [x]
    | otherwise = compdivides (abs x)

I understand that if x is positive we do the 3rd line otherwise the 4th line.

In the third line we check whether mod x a == 0 only then do we do everything else.

However, I cannot seem to understand this part a <-[1..div x 2] What exactly happens here?

Also, why do we do this at the end ++ [x] ? What exactly are we doing here anyways?

itemTotal :: [(String, Float)] -> [(String, Float)]
itemTotal [] = []
itemTotal [x] = [x]

I am having some trouble with this as well. I understand that if the list is empty we simply return an empty list.

However, what are we saying here? itemTotal [x] = [x] That if the list only has one thing we simply return that one thing?

Thank you so much for the help!

1 Answers

However, I cannot seem to understand this part a <-[1..div x 2] What exactly happens here?

This is a generator of the list comprehension. The list comprehension:

[ a | a <- [1 .. div x 2 ], mod x a == 0 ]

will evaluate such that a takes each item in the list (so 1, 2, …, x/2), and in case mod x a == 0 (x is dividable by a), it will add a to the list.

Also, why do we do this at the end ++ [x] ? What exactly are we doing here anyways?

It appends x at the end of the list. This is done because a number x is always dividable by itself (x), since the a <- [1 .. div x 2] stops at div x 2, it will never check if x divides x.

The function will get stuck in an infinite loop for compdivides 0, so you might want to rewrite the function to cover this case as well.

However, what are we saying here? itemTotal [x] = [x] That if the list only has one thing we simply return that one thing?

Yes. Usually a pattern like itemTotal (x : xs) = x : itemTotal xs is used where we thus return a list where x is the first item, and we recurse on the tail of the list xs.

Your itemTotal function however only makes a copy of the list for the first two clauses. You thus can simply define itemTotal = id. Likely you will need to rewrite the function to determine the total of the items in the list.

Related