views:

142

answers:

3

Hi everyone,

I'm trying to write a function that takes in a list and returns true if it is in sorted order and false if not:

So far what I have is:

myordered [] = True
myordered [x] = True
myordered list1
 | (head list1) <= (head (tail list1)) = myordered(tail list1)
 | otherwise                           = False

Based on our assignment, all head and tail operations should be written down as "x:xs" type syntax.

the translation I come up with for the section with a guard is:

myordered y:x:xs
 | (y) <= (x) = myordered(xs)
 | otherwise  = False

Essentially this question boils down to: How do you express the (head (tail list1)) in "x:xs" type syntax?

Cheers, -Zigu

+8  A: 

Your pattern is almost correct, you just need to surround it with parentheses:

myordered (y:x:xs)

Also note that there's no need to surround y and x with parentheses in y <= x.

Also there's a semantic mistake in your second version:

myordered(xs) here xs refers to the tail of tail, but you want the whole tail, so you should do myordered (x:xs) or alternatively:

myordered (y:xs@(x:_))
 | y <= x = myordered xs
 | otherwise  = False

Which says: xs is the tail of that list, x is the head of that tail, and _ (which is ignored) is the tail of the tail.

sepp2k
Since this is homework, reconstructing the tail may be easier to understand: myordered (y:x:xs) | y <= x = myordered (x:xs).
yatima2975
@yatima: Well, that was the first option I gave.
sepp2k
Sorry! I wasn't reading properly.
yatima2975
+4  A: 

How about another way to do this with the help of zipWith function available in Data.List

 myordered xs= and $ zipWith (<=) xs (tail xs)

zipWith function takes two list and apply a function. Here it will return an array of boolean according to the condition .
and takes a list of boolean values and returns True only if all the values in the list are True

jijesh
This is a beautiful idiomatic solution... that a beginner would not write. I think the teacher would catch on :-P
luqui
I like it. The only thing I'd change is 'drop 1' instead of 'tail', so that it works on [].
mokus
Thanks mokus [] will work with tail as well.
jijesh
`zipWith` will handle [] , so tail function inside `zipWith` will work without any exception
jijesh
Ah, true. Nevermind then, it's perfect :)
mokus
A: 

How about

isordered :: [Int] →  Bool
isordered [] = True
isordered xs = foldl (&&) True $ zipWith (<=) xs $ tail xs

Oh, and just for fun:

isordered :: [Int] →  Bool
isordered [] = True
isordered (x:xs) = (foldl comp (Just x) xs) /= Nothing
   where comp (Just a) b = if a ≤ b then Just b else Nothing
         comp Nothing _ = Nothing  
Landei