我们必须编写一个具有更高阶函数的代码。它应该只有一个句子。 如果已排序,将检查给定列表。 到目前为止,我有这个:
compare (a:xs) = foldl (\a b -> a < b ) True a xs || foldl (\a b -> a > b ) True
我总是收到错误消息:coul not match expected bool witch实际类型t0 Bool - &gt;布尔。这是什么意思?
答案 0 :(得分:2)
提示1:foldl
的第三个参数必须是列表,a
不是。
提示2:使用你的折叠,
foldl (\a b -> a < b) base [1,2,3]
= (((base < 1) < 2) < 3)
这里出了点问题:base < 1
的结果是布尔值,之后我们无法将其与2
进行比较。
因此,您的函数\a b -> a < b
在此上下文中看起来有误:它的类型错误。
答案 1 :(得分:0)
好的,我会尝试给你一些帮助,告诉你如何做到这一点。
首先你应该注意,为了检查列表是否已排序,你通常比较连续的元素并检查它们是否在升序 - 请注意你必须使用两个连续的元素
现在foldl
和foldr
让您一次只能看到其中一个 - 所以您可能必须记住 之前的元素以某种方式看到了 - 唯一能做到这一点的地方就是把它包含在你的州里。
这可以通过各种方式完成,但我建议使用元组。
所以不是状态是到目前为止排序的列表我会但是在元组中(到目前为止排序的列表,前一个元素)。
这是一个简单的模板,你必须填写一些东西:
isSorted :: Ord a => [a] -> Bool
isSorted (x:xs) = _A (foldl (\ (sorted,prev) cur -> (_B, _C)) (_D, _E) (_F))
如果你尝试这个,这将无法编译,因为你必须考虑一些漏洞(如果你加载它GHC(i)将帮助你的类型):
_E
,_F
应分别有a
和[a]
类型,提示 _E
应该是第一个你看到的前一个元素 - 因为检查空列表的这个谓词是没用的,你可能会以某种方式使用xs
和x
;)_D
应该有Bool
_C
应该有a
类型,并且是您的下一个之前的元素_B
应该有Bool
类型 - 这是肉体的地方 - 基本上就是你已经尝试过的_A
应该有(Bool, a) -> Bool
类型,你可以弄明白。我会在一个小时左右的时间内给出解决方案以完成这个答案 - 但你应该自己尝试做到这一点
isSorted :: Ord a => [a] -> Bool
isSorted [] = True
isSorted (x:xs) = fst (foldl
(\ (sorted,prev) cur -> (sorted && prev <= cur, cur))
(True, x)
xs)