In the following code you have to write a function to check if a list is sorted or not.
isOrd :: [Int] -> Bool
isOrd [] = True
isOrd [_] = True
isOrd (x:y:xs) = x<=y && isOrd (y:xs)
I would like to know why there is no need to write if/then/else or case for the last line? Why don't we need to check if it's True
or False
?
CodePudding user response:
What if/then/else would you propose writing? The one I would imagine would look something like this:
isOrd (x:y:xs) = if x<=y && isOrd (y:xs)
then True
else False
But we know that if x then True else False
is always just a particularly long-winded way to write x
. So there's not really any need for a specific conditional branch here: we can just return the condition itself.
CodePudding user response:
That is checked by the (&&) :: Bool -> Bool -> Bool
function: if the left operand is False
, it returns False
. If the left operand is True
, it returns the right operand.
Indeed, the function is implemented as [src]:
(&&) :: Bool -> Bool -> Bool True && x = x False && _ = False
It thus will check the first operand, and based on that either return False
, or recurse on the rest of the function.
CodePudding user response:
like why we don't need to check if it's True or False?
Because the function's output type is Bool
and it is enough for us just return Bool
as amalloy mentioned.
So, firstly we said that empty list and list with one element are sorted lists. Then we said: "check if the first element of the list is less or equal then the second. If it isn't then return False
. If it is then check if the same list without the first element is sorted". And this is enough to return the right Bool
for all input lists.