Writing Haskell code that drop every nth element from a list

Hello .
I am writng a code that drop every n-th element from a list:
for example
dropevery [0,1,2,3,4,5,6,7,8,9] 3
->[0,1,3,4,6,7,9] this list show up.2,5,8 were droped from the list because those numbers are every 3rd element in the list.

my code is like
dropevery :: [a] → Int → [a]
–base case
dropevery [] = []

dropevery (x:xs) = x: (dropevery (remove x xs))
where
remove :: Int → [Int] → [Int]
remove x [] = []
remove x (y:ys)
| x==y = remove x ys
|otherwise = y:(remove x ys)

functioncall = dropevery[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]3
main = putStrLn (show functioncall)

I want drop 3,6,9,12,15 from the list, but I got some error.

Could anyone tell and teach me what is/are wrong with my code and fix it/them for me?

Hi,

first please format/mark your code - thanks.

Do your problem start here:

dropevery :: [a] -> Int -> [a]
dropevery [] = []

you should already see an error here - you did not bind/name/declare (whatever you might call it) the argument for the Int - so the typechecker sees [] (some empty list) but your signature says this should be a function Int -> [a].

Try

dropevery :: [a] -> Int -> [a]
dropevery [] _ = []

Then I think you’ll find this easier without trying to write this with remove but in this form:

dropevery :: [a] -> Int -> [a]
dropevery xs n = go 0 xs
    where go _ [] = []
          go i (y:ys) | i == n = ?
                      | otherwise = ?
    

The idea is to to use a helper that moves along the list counting up i and of course once you’ll reach n you want to drop the current element (and continue with i=0 again).
Think about how you can express this with recursive calls to go where I put the ?


Depending on how far you are into your course (I guess this is some form of exercise / homework) you might be able to use/reuse some functions.
For example if you’ve already seen zip, filter and map there is a nice solution where you pair up the elements in the list with their indizes (it’s a default trick you’ll probably see in the lessons: zip [1..] xs) - then you can use this index X element paired list to filter out all elements where index mod n == 0 and then use map to drop the index again - this could turn out into one of those nice Haskell one-liners:

dropevery :: [a] -> Int -> [a]
dropevery xs n = map (..?..) $ filter (..?..) $ zip [1..] xs
3 Likes