rlh*_*lhh 9 haskell functional-programming
Haskell中是否有任何库函数可以让我检查列表是否连续排序?例如.[1,2,3,4]有效,[1,2,3,10]无效.
基本上我可以有一个范围在3到5个元素之间的列表,我正在尝试检查该列表是否连续排序.
我的尝试(我不确定这是否是接近它的正确方法,似乎过多的重复)
isSucc:: [Integer] -> Bool
isSucc[] = True
isSucc(x:y:zs) =
if (x+1) == y
then True && isSucc(y:zs)
else isSucc(y:zs)
Run Code Online (Sandbox Code Playgroud)
在我使用此功能之后,我计划使用它来过滤列表列表(仅将列表保留在列表中,并且仅在连续排序时)
Mat*_*hid 14
您可以使用该技巧zipWith f xs (drop 1 xs)应用于f连续的列表元素对.(注意drop 1而不是tail,因为如果列表为空,后者会失败!)
如果您更换f同<=你会得到一个列表Bool值.现在看看他们是否全部True.
isSucc xs = and $ zipWith (<=) xs (drop 1 xs)
Run Code Online (Sandbox Code Playgroud)
没有标准功能.
这是您的函数的固定版本,使其成为通用版本,删除冗余条件并添加缺少的条件:
isSucc :: (Enum a, Eq a) => [a] -> Bool
isSucc [] = True
isSucc (x:[]) = True
isSucc (x:y:zs) | y == succ x = isSucc $ y:zs
isSucc _ = False
Run Code Online (Sandbox Code Playgroud)
我更喜欢使用比MathematicalOrchid提供的解决方案更易读的解决方案.
首先,我们将定义实用功能成对,可能在许多不同的情况下是有用的:
pairwise xs = zip xs $ tail xs
Run Code Online (Sandbox Code Playgroud)
或以更现代的方式:
import Control.Applicative ((<*>))
pairwise = zip <*> tail
Run Code Online (Sandbox Code Playgroud)
然后将其与其他组合器一起使用:
isSucc xs = all (\(x,y) -> succ x == y) $ pairwise xs
Run Code Online (Sandbox Code Playgroud)