module Data.List.Extra where
updateAt :: Int -> a -> [a] -> [a]
updateAt _ _ [] = []
updateAt 0 x (_:xs) = x : xs
updateAt i x (y:xs) = y : updateAt (i1) x xs
deleteAt :: Int -> [a] -> [a]
deleteAt _ [] = []
deleteAt 0 (_:xs) = xs
deleteAt i (x:xs) = x : deleteAt (i1) xs
elemAt :: Int -> [a] -> Maybe a
elemAt _ [] = Nothing
elemAt 0 (x:_) = Just x
elemAt i (_:xs) = elemAt (i1) xs
shiftLeftWith :: (a -> Bool) -> [a] -> [a]
shiftLeftWith f (x1:x2:xs)
| f x2 = x2 : x1 : xs
| otherwise = x1 : shiftLeftWith f (x2:xs)
shiftLeftWith _ xs = xs
shiftRightWith :: (a -> Bool) -> [a] -> [a]
shiftRightWith f (x1:x2:xs)
| f x1 = x2 : x1 : xs
| otherwise = x1 : shiftRightWith f (x2:xs)
shiftRightWith _ xs = xs
shiftLeftAt :: Int -> [a] -> [a]
shiftLeftAt i ls@(x1:x2:xs)
| i < 1 = ls
| i == 1 = x2 : x1 : xs
| otherwise = x1 : shiftLeftAt (i 1) (x2:xs)
shiftLeftAt _ xs = xs
shiftRightAt :: Int -> [a] -> [a]
shiftRightAt i ls@(x1:x2:xs)
| i < 0 = ls
| i == 0 = x2 : x1 : xs
| otherwise = x1 : shiftRightAt (i 1) (x2:xs)
shiftRightAt _ xs = xs