module CustomList where

data List a = Nil | Cons a (List a)
                    deriving Show

emptyList :: List a
emptyList = Nil

isEmpty :: List a -> Bool
isEmpty Nil = True
isEmpty (Cons _ _) = False

cons :: a -> List a -> List a
cons = Cons

head :: List a -> a
head Nil = error "Empty list"
head (Cons x _) = x

tail :: List a -> List a
tail Nil = error "Empty list"
tail (Cons _ xs) = xs

append :: List a -> List a -> List a
append Nil ys = ys
append (Cons x xs) ys = Cons x (append xs ys)

update :: List a -> Int -> a -> List a
update Nil _ _ = error "Empty list"
update (Cons _ xs) 0 y = Cons y xs
update (Cons x xs) i y = Cons x (update xs (i - 1) y)

-- | Compute suffixes of a list
--
-- Examples:
--
-- >>> suffixes Nil
-- Nil
--
-- >>> suffixes (Cons 1 Nil)
-- Cons (Cons 1 Nil) Nil
--
-- >>> suffixes (Cons 1 (Cons 2 (Cons 3 Nil)))
-- Cons (Cons 1 (Cons 2 (Cons 3 Nil))) (Cons (Cons 2 (Cons 3 Nil)) (Cons (Cons 3 Nil) Nil))
suffixes :: List a -> List (List a)
suffixes Nil = Nil
suffixes (Cons x xs) = Cons (Cons x xs) (suffixes xs)
