我想使用until
回复this question。但这不起作用,我得出的结论是我不理解until
。
所以我接受OP给出的功能,逐字:
removeAdjDups :: (Eq a) => [a] -> [a]
removeAdjDups [] = []
removeAdjDups [x] = [x]
removeAdjDups (x : y : ys)
| x == y = removeAdjDups ys
| otherwise = x : removeAdjDups (y : ys)
然后我写一个True/False
函数重新调整是否存在重复:
hasAdjDups :: (Eq a) => [a] -> Bool
hasAdjDups [] = False
hasAdjDups [x] = False
hasAdjDups (x : y : ys)
| x == y = True
| otherwise = hasAdjDups (y : ys)
最后我使用until
如下:
f :: (Eq a) => [a] -> [a]
f x = until hasAdjDups removeAdjDups x
这不起作用:
> hasAdjDups "aabccddcceef"
True
> removeAdjDups "aabccddcceef"
"bf"
> f "aabccddcceef"
"aabccddcceef"
我误解了until
,或者我犯了错误?
答案 0 :(得分:8)
until :: (a -> Bool) -> (a -> a) -> a -> a
记录为:
until p f
会产生应用f
直到p
成立的结果。
它的实现方式如下:
until p f = go where go x | p x = x | otherwise = go (f x)
因此,您提供谓词p
和函数f
。该函数也被赋予初始值x
。通过使用递归,它首先检查p x
是否成立。如果是,则返回x
,否则,它会使用f x
作为新x
进行递归调用。
所以实现更干净(但效率更低)的实现可能是:
until p f x | p x = x
| otherwise = until p f (f x)
如果我们分析您的功能,我们会看到:
f x = until hasAdjDups removeAdjDups x
这意味着f
将终止从 相邻的重复字符时删除相邻的重复字符。你可能想要相反的谓词:
f x = until (not . hasAdjDups) removeAdjDups x
甚至更短:
f = until (not . hasAdjDups) removeAdjDups
答案 1 :(得分:3)
您可能忘记了not
:
f :: (Eq a) => [a] -> [a]
f x = until (not . hasAdjDups) removeAdjDups x
f "aabccddcceef" -- "bf"
答案 2 :(得分:2)
好吧,dataObj.Root["variables"]["temperature"]["dataType"].Replace("string");
重复将转换应用于值,直到谓词匹配。在您的情况下,输入已经until
,因此永远不会调用hasAdjDups
。您可能正在寻找removeAdjDups
:
while