[英]How does `until` work?
我想用until
回答這個問題 。 但這不起作用,我得出結論, 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
,或者我做了一個錯誤?
until :: (a -> Bool) -> (a -> a) -> a -> a
記錄為:
until pf
產生應用f
的結果直到p
成立 。
它實現如下:
until pf = go where go x | px = x | otherwise = go (fx)
所以你提供了一個謂詞p
和一個函數f
。 該函數還給出了初始值x
。 通過使用遞歸,它首先檢查px
成立。 如果是,它返回x
,否則,它使用fx
作為新x
進行遞歸調用。
因此,更干凈(但效率更低)的實現可能是:
until p f x | p x = x
| otherwise = until p f (f x)
如果我們分析您的功能,我們會看到:
f x = until hasAdjDups removeAdjDups x
因此,這意味着f
將terminale從它相鄰的重復字符的瞬間去除相鄰重復字符。 你可能想要相反的謂詞:
f x = until (not . hasAdjDups) removeAdjDups x
甚至更短:
f = until (not . hasAdjDups) removeAdjDups
你可能忘了not
:
f :: (Eq a) => [a] -> [a]
f x = until (not . hasAdjDups) removeAdjDups x
f "aabccddcceef" -- "bf"
好吧, until
重復應用轉換到值, 直到謂詞匹配。 在您的情況下,輸入已經具有hasAdjDups
,因此從不調用removeAdjDups
。 你可能會尋找while
:
while = until . (not .)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.