在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, ....]
有没有办法解决这个错误?
答案 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)