Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Checking to see if a list is ordered consecutively

Is there any library function in Haskell that'll allow me to check if a list is ordered consecutively? eg. [1,2,3,4] is valid, [1,2,3,10] is invalid.

Basically I can have a list that ranges anywhere between 3 to 5 elements and I'm trying to check if that list is ordered consecutively.

My Attempt (I'm not sure if this is the right way to approach it, seems to be way too much repetition)

isSucc:: [Integer] -> Bool
isSucc[]            = True
isSucc(x:y:zs)      = 
    if (x+1) == y
    then True && isSucc(y:zs)
    else isSucc(y:zs)

After I have this function working, I'm planning on using it to filter a lists of lists (Keep the list inside the list only and only if it is ordered consecutively)

like image 854
rlhh Avatar asked Mar 21 '13 08:03

rlhh


3 Answers

You can use the trick zipWith f xs (drop 1 xs) to apply f to consecutive pairs of list elements. (Notice drop 1 rather than tail, because the latter fails if the list is empty!)

If you replace f with <= you'll get a list of Bool values. Now see whether they're all True.

isSucc xs = and $ zipWith (<=) xs (drop 1 xs)
like image 120
MathematicalOrchid Avatar answered Nov 21 '22 12:11

MathematicalOrchid


There's no standard function for that.

Here's a fixed version of your function, making it generic, removing the redundant conditions and adding the missing ones:

isSucc :: (Enum a, Eq a) => [a] -> Bool
isSucc [] = True
isSucc (x:[]) = True
isSucc (x:y:zs) | y == succ x = isSucc $ y:zs
isSucc _ = False
like image 36
Nikita Volkov Avatar answered Nov 21 '22 11:11

Nikita Volkov


I prefer to use a little more readable solution than one that has been offered by MathematicalOrchid.

First of all we will define the utilitarian function pairwise that might be useful in many different circumstances:

pairwise xs = zip xs $ tail xs

or in more modern way:

import Control.Applicative ((<*>))

pairwise = zip <*> tail

and then use it with the other combinators:

isSucc xs = all (\(x,y) -> succ x == y) $ pairwise xs
like image 20
Shaggie Avatar answered Nov 21 '22 11:11

Shaggie