module JoinList where import Sized data JoinList m a = Empty | Single m a | Append m (JoinList m a) (JoinList m a) deriving (Eq, Show) -- Exercise 1 tag :: Monoid m => JoinList m a -> m tag Empty = mempty tag (Single m _) = m tag (Append m _ _) = m (+++) :: Monoid m => JoinList m a -> JoinList m a -> JoinList m a (+++) jl1 jl2 = Append (mappend (tag jl1) (tag jl2)) jl1 jl2 -- Exercise 2 indexJ :: (Sized b, Monoid b) => Int -> JoinList b a -> Maybe a indexJ _ Empty = Nothing indexJ n (Single _ a) | n == 0 = Just a | otherwise = Nothing indexJ n (Append m jl1 jl2) | n < 0 || n >= (getSize $ size m) = Nothing | n < s1 = indexJ n jl1 | n >= s1 = indexJ (n - s1) jl2 where s1 = getSize $ size $ tag jl1 dropJ :: (Sized b, Monoid b) => Int -> JoinList b a -> JoinList b a dropJ _ Empty = Empty dropJ n jl | n <= 0 = jl dropJ n (Single _ _) | n >= 1 = Empty dropJ n (Append m jl1 jl2) | n >= (getSize $ size m) = Empty | n >= s1 = jl2 where s1 = getSize $ size $ tag jl1