检查是否连续订购列表

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)

  • 实际上,在这种情况下使用`zipWith`时,`tail`很好,因为命令`zipWith`的意外事件会评估它的参数.但是,按顺序评估它的参数并不是偶然的. (4认同)
  • 只是为了记录,为了匹配问题,那将是`和$ zipWith((==).succ)xs(tail xs)`. (4认同)

Nik*_*kov 9

没有标准功能.

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

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)


Sha*_*gie 5

我更喜欢使用比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)