I have the following function:
longer x y | y < 0 = error "negative value"
| length x > y = True
| length x <= y = False
Where x
is type [a]
and y
is type Int
.
This function works fine for finite lists but doesn't evaluate and goes into an infinite loop when I enter an infinite list. What other approach should I try?
My attempt:
In the case of longer [1..] 10
, I would start at the first value, compare the length of the list (so [1]
) with 10, if the length is smaller, then move on to the first two values, compare the list's (so [1,2]
) length with 10, see that the statement is still false, moving on to the first three values etc. I think recursion might be the correct way to approach this problem of mine.
CodePudding user response:
You see, if a list is passed to a function, it can be of two shapes, either it is empty
length [] y = undefined
or it consists of a value and the rest of the list
length (x:xs) y = undefined
These are the only two cases, because the list data type is defined that way:
Prelude> :info []
data [] a = [] | a : [a] -- Defined in `GHC.Types'
So you have already made progress by splitting your original problem into two smaller parts. And you are probably able to implement the first case (the empty list). But note that you have also made progress for the second case. While previously you knew nothing of the original list x
(which is better named xs
instead), you now know that the original list is of shape x : xs
. Here x
is the first item of the list and xs
is the remaining list. In particular you know now, that the passed list was at least of size 1. And this is true regardless of the remaining list xs
. Are you now able to implement
length (x:_) 0 = undefined
If so, what about the case where y
is not zero:
length (x:xs) y = undefined
Can you ask a new question about xs
and y
instead of x:xs
and y
? Remember, that you know that xs
is one item shorter than x : xs
.