The reason yours is not working is that your else branch does not produce an list inside your function - you can easily fix the syntax issue like this:
duplicate xs =
[ y | x <- xs
, i <- [0..]
, y <- if i `mod` 2 == 0
then replicate 2 x
else [x] ]
but this would give you nothing but an endless list of the first thing in xs (because there are infinite many is)
Now my guess is that you indeed want to replicate every other element 2 times and yes zip is a great idea and you are almost there (with your comment):
just make sure that you fix the syntax/type error there as well:
duplicate xs =
[ y | (i, x) <- zip [0..] xs
, y <- if i `mod` 2 == 0
then replicate 2 x
else [x] ]
this will give you:
λ> duplicate "Hello"
"HHellloo"
which is hopefully what you are looking for
exercise
You can rewrite this into
duplicate = concat . zipWith replicate (cycle [2, 1])
try to find out how this works
Hint: it's based on the idea of: take 2 of the first, then 1 of the second, then 2 of the third, then 1 of the forth, ... - only obfuscated by Haskells higher-order function and operator zoo ;)