测试列表是否已排序

时间:2014-02-26 19:00:03

标签: haskell

在haskell中找到最少的列表非常容易:

foldl1 (min) [9,5,7,3,7,4,6,10]给了我3。 ;)

我将min替换为<=以测试列表是否已排序:

foldl1 (<=) [9,5,7,3,7,4,6,10]

我收到此错误消息:

No instance for (Num Bool) arising from the literal `9'
Possible fix: add an instance declaration for (Num Bool)
In the expression: 9
In the second argument of `foldl1', namely `[9, 5, 7, 3, ....]'
In the expression: foldl1 (<=) [9, 5, 7, 3, ....]

有没有办法解决这个错误?

5 个答案:

答案 0 :(得分:5)

是。从我们的基本情况开始

isSorted [] = True -- An empty list is sorted

现在为非空案例

isSorted (x:xs) = fst $ foldl' step (True, x) xs
  where step (b, x) y = (b && (x <= y), y)

基本上我们在元组的第一个参数和第二个元素中跟踪排序状态,然后我们更新排序状态和每一步的值。

虽然这不是懒惰,但不适用于无限列表,而是尝试

 import Control.Applicative

allSorted :: Ord a => [a] -> Bool
allSorted = all (uncurry (<=)) . (zip <$> id <*> tail)
allSorted = all (uncurry (<=)) . (zip <*> tail)
allSorted = and . (zipWith (<=) <*> tail)

答案 1 :(得分:2)

foldl1具有以下类型:

foldl1 :: (a -> a -> a) -> [a] -> a

但是,(<=)的类型为a -> a -> Bool,除非a不是Bool,否则foldl1不适用foldl1。所以你不能以这种方式使用isSorted :: (Ord a) => [a] -> Bool isSorted [] = True isSorted [x] = True isSorted (x:y:xs) = x <= y && isSorted (y:xs) 。可能的解决方案是

x <= y

但是,您也可以使用后继方法压缩每个元素,然后检查isSorted' :: (Ord a) => [a] -> Bool isSorted' xs = all id . map (\(x,y) -> x <= y) . zip xs $ tail xs 是否成立:

{{1}}

答案 2 :(得分:2)

这适用于升序和降序

sorted a = same $ map (>0) $ filter (/=0) $ zipWith (-) a (tail a)
 where
   same (x:xs) = and $ map (==x) xs

测试用例

> sorted [1..10]
True
> sorted [10,9..1]
True
> sorted [1,4,3]
False
> sorted [71,3,3,2]
True
> sorted [1,1,3]
True

答案 3 :(得分:2)

这是一个有趣的问题。如上所述,这些类型最初并不匹配,但我决定试一试。

我开始使用压缩:

sorted  xs = foldr (&&) True (map (\(a,b) -> a<=b) (zip xs (tail xs)))

我不喜欢它所以我尝试使用元组:

sorted2 xs = (\(x,y) -> y) (foldl (\(x,y) a -> (a,x<=a && y)) (head xs, True) xs)

我对此并不满意,因为这个功能并没有从折叠开始。我试着回去拉链,这次我用折叠定义了拉链:

zip1 = foldr (\ a f bs -> if null bs then [] else (a,(head bs)):(f (tail bs))) (const [])

这给了我一个主意。如您所见,累加器是一个函数,折叠返回一个函数。因此,我们可以对已排序的函数执行相同的操作:

sorted3 [] = True
sorted3 xs = foldr (\a f b -> (a >= b) && f a) (const True) (tail xs) (head xs)

有了这个我很高兴。 编辑:为sorted3添加空列表检查我忘了添加。

答案 4 :(得分:0)

这是我的解决方案,他们借鉴了以前的答案:

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

isSorted xs = all (<=0) $ zipWith (-) xs (tail xs)