How does `do` work?

I wanted to answer this question using until. But this does not work, and I came to the conclusion that I do not understand until.

So, I take the function given by OP, verbatim:

removeAdjDups :: (Eq a) => [a] -> [a]
removeAdjDups []           =  []
removeAdjDups [x]          =  [x]
removeAdjDups (x : y : ys)
  | x == y = removeAdjDups ys
  | otherwise = x : removeAdjDups (y : ys)

Then I write a function True/Falsethat returns if there is a duplicate:

hasAdjDups :: (Eq a) => [a] -> Bool
hasAdjDups []           =  False
hasAdjDups [x]          =  False
hasAdjDups (x : y : ys)
  | x == y = True
  | otherwise = hasAdjDups (y : ys)

Finally, I use untilas follows:

f :: (Eq a) => [a] -> [a]
f x = until hasAdjDups removeAdjDups x

And this does not work:

> hasAdjDups  "aabccddcceef"
True
> removeAdjDups   "aabccddcceef"
"bf"
> f "aabccddcceef"
"aabccddcceef"

Am I misunderstanding until, or have I made a mistake?

+4
source share
3 answers

until :: (a -> Bool) -> (a -> a) -> a -> a documented as:

until p fgives the result of the application f, until pit is .

It is implemented as:

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
+8

, not:

f :: (Eq a) => [a] -> [a]
f x = until (not . hasAdjDups) removeAdjDups x

f "aabccddcceef" -- "bf"
+3

Well, untilreapplies the conversion to the value until the predicate matches. In your case, the input is already hasAdjDups, so it is removeAdjDupsnever called. You are probably looking for while:

while = until . (not .)
+2
source

Source: https://habr.com/ru/post/1695198/


All Articles