“直到”如何运作?

时间:2018-03-22 08:12:08

标签: haskell

我想使用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,或者我犯了错误?

3 个答案:

答案 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