-2

I have the following function and should write it with foldr.

f [] = []
f (x:xs)
  | x == 0 = case f xs of
               [] -> []
               ys@(y:_) -> if y == 0 then ys else x : ys
  | otherwise = x : f xs

This function basically removes all trailing 0's, but keeps at most one leading 0.

For example:

f [1,2,0,0] = [1,2]

f [1,2,0,1] = [1,2,0,1]

f [0,0,1,0,0,3] = [0,1,0,3]

I have foldr op z lst, but don't know what op can be. z should be [].

Example I traced:

foldr op [] [0,0,1,0,0,3]

-> 0 op (0 op (1 op (0 op (0 op (3 op []))))

                                |-- [3] ---|
                           |---[0,3] ------|
                     |-----[0,3]-----------|
               |-----[1,0,3]---------------|
         |-----[0,1,0,3]-------------------|
   |-----[0,1,0,3]-------------------------|
K Split X
  • 3,405
  • 7
  • 24
  • 49
  • 1
    `op x w` should be the same as the definition of `f (x:xs)`, except you need to use `w` instead of the recursive call `f xs`. – chi Mar 13 '19 at 22:37

1 Answers1

1

How about

f = fst . foldr (\ x (xs', y) -> if y && x == 0 then (xs', x==0) else (x:xs', x==0 )) ([], True)

in this case, op returns a tuple of list and Bool, Bool is for tracking whether the accumulated list started with 0. At the end, we use fst to discard the Bool. We have to use ([], True) as the initial value, to handle the trailing zero case.

Yuan Wang
  • 479
  • 2
  • 13