Haskell 检查列表是否连续排序

Haskell 检查列表是否连续排序,haskell,functional-programming,Haskell,Functional Programming,Haskell中是否有任何库函数允许我检查列表是否连续排序?[1,2,3,4]是有效的,[1,2,3,10]是无效的 基本上,我可以有一个范围在3到5个元素之间的列表,我试图检查这个列表是否是连续排列的 我的尝试(我不确定这是否是正确的方法,似乎重复太多) 在这个函数运行之后,我计划使用它来过滤列表列表(仅当列表连续排序时才将列表保留在列表中)您可以使用带有f xs(drop 1 xs)的技巧将f应用于连续的列表元素对。(注意drop 1而不是tail,因为如果列表为空,后者将失败!) 如果用替

Haskell中是否有任何库函数允许我检查列表是否连续排序?[1,2,3,4]是有效的,[1,2,3,10]是无效的

基本上,我可以有一个范围在3到5个元素之间的列表,我试图检查这个列表是否是连续排列的

我的尝试(我不确定这是否是正确的方法,似乎重复太多)


在这个函数运行之后,我计划使用它来过滤列表列表(仅当列表连续排序时才将列表保留在列表中)

您可以使用带有f xs(drop 1 xs)的技巧
将f
应用于连续的列表元素对。(注意
drop 1
而不是
tail
,因为如果列表为空,后者将失败!)


如果用
替换
f
,则没有标准的函数

下面是函数的固定版本,使其通用,删除冗余条件并添加缺少的条件:

isSucc :: (Enum a, Eq a) => [a] -> Bool
isSucc [] = True
isSucc (x:[]) = True
isSucc (x:y:zs) | y == succ x = isSucc $ y:zs
isSucc _ = False

我更喜欢使用一个比我们提供的更具可读性的解决方案

首先,我们将两两定义在许多不同情况下可能有用的实用功能:

pairwise xs = zip xs $ tail xs
或者以更现代的方式:

import Control.Applicative ((<*>))

pairwise = zip <*> tail

还有另外一种方式,

isOrdered :: (Enum a, Eq a) => (a -> a -> Bool) -> [a] -> Bool
isOrdered op (a:b:ls) = op a b && isOrdered op (b:ls)
isOrdered op _ = True
因此,

isSucc = isOrdered ((==) . succ)

如果要检查所有连续差异是否等于一,可以使用

isIncreasingByOne::(等式a,数值a)=>[a]->Bool isIncreasingByOne=all(=1)(带(-)(尾部X)的拉链)

这适用于数字类型(因此有
numa
约束),包括
Float
Double
。如果您想检查一个序列一次增加5个以上,也可以很容易地进行调整。

--这会检查序列是否有序

isordd:: [Int] -> Bool 
isordd [] = True
isordd (x:y:xs) 
 | x > y = False
 | lengh xs == 0 = True
 | otherwise = isordd (y:xs)
--这将计算列表的长度

lengh::[Int]->Int
lengh [] = 0
lengh (x:xs) = 1+lengh xs

误解问题的方式!但是,应该清楚地知道如何更改
f
以使其满足您的需要。我从来没有想过要改为使用drop 1。似乎是一个更好的实现方案,但是与
(x:xs)
相比,
drop 1xs
会更昂贵吗?实际上,
tail
在本例中与
zipWith
一起使用时很好,因为顺序的意外情况是
zipWith
在中计算其参数。但它以这种顺序评估其参数并不是偶然的。为了记录在案,为了匹配问题,这将是
和$zipWith((==).succ)xs(tail xs)
。此解决方案不符合OP的要求,并且与@matemachicalrorchid的解决方案一样错误。请看我对他的回答的评论:我喜欢你如何使用函数的Applicative实例来编写
。仍然试图让我的头围绕着它)头脑弯曲的东西!这是不正确的——OP希望检查元素是否连续,而不仅仅是它们是否有序。你可以用
isSucc=isOrdered((==).suc)来纠正这个问题。
我很高兴看到每一张海报都像我一样误读了这个问题。:-)
isSucc = isOrdered ((==) . succ)
isordd:: [Int] -> Bool 
isordd [] = True
isordd (x:y:xs) 
 | x > y = False
 | lengh xs == 0 = True
 | otherwise = isordd (y:xs)
lengh::[Int]->Int
lengh [] = 0
lengh (x:xs) = 1+lengh xs