Search code examples
listhaskellrecursionguard

Haskell how to drop all 0 of the list until one of the elements /= 0?


I'm new to Haskell and I'm trying to figure out how to write a code, that drops all zeros until an element of the list is >0.

So for example:

Input: [0,0,5,6,0]

Output: [5,6,0]

So far I have wrote this:

zeroUntil :: [Int] -> [Int]
zeroUntil [] = []
zeroUntil (x:xs)
    | x == 0 = drop x (xs)
    | otherwise = zeroUntil xs

But somehow intead of [5,6,0] i get [ ].

Can anybode please explain what did I do wrong?


Solution

  • You can make use of dropWhile :: (a -> Bool) -> [a] -> [a] and thus drop items as long as these are zeros:

    zeroUntil :: [Int] -> [Int]
    zeroUntil = dropWhile (0 ==)

    If you want to drop zeros until an element is greater than zero, you can make use of recursion. Here your recursive case should yield elements if these are less than zero:

    zeroUntil :: [Int] -> [Int]
    zeroUntil [] = []
    zeroUntil (0:xs) = zeroUntil xs
    zeroUntil (x:xs)
        | x > 0 = x : xs  -- ← end of recursion, return the list
        | otherwise = x : zeroUntil xs  -- ← yield x and recurse

    for example:

    Prelude> zeroUntil [0,0,5,6,0]
    [5,6,0]
    Prelude> zeroUntil [0,-1,5,6,0]
    [-1,5,6,0]