1 {-# OPTIONS_GHC -Wall #-}
7 data JoinList m a = Empty
9 | Append m (JoinList m a) (JoinList m a)
13 tag :: Monoid m => JoinList m a -> m
16 tag (Append t _ _) = t
18 (+++) :: Monoid m => JoinList m a -> JoinList m a -> JoinList m a
21 alst1 +++ alst2 = Append ((tag alst1) `mappend` (tag alst2)) alst1 alst2
25 indexJ :: (Sized b, Monoid b) =>
26 Int -> JoinList b a -> Maybe a
27 indexJ _ Empty = Nothing
28 indexJ n _ | n < 0 = Nothing
29 indexJ n (Single _ a) | n == 0 = Just a
31 indexJ n (Append t l r) | n >= getSize (size t) = Nothing
33 | n < (getSize (size (tag l))) = indexJ n l
34 | otherwise = indexJ (n - getSize (size (tag l))) r
37 dropJ :: (Sized b, Monoid b) =>
38 Int -> JoinList b a -> JoinList b a
42 dropJ n v@(Single _ _) | n == 0 = v
44 dropJ n (Append t l r) | n > getSize (size t) = Empty
46 dropJ (n - leftSize) r
47 | otherwise = let lft = dropJ n l in
48 Append ((tag lft) `mappend` (tag r)) lft r
49 where leftSize = getSize . size . tag $ l
52 takeJ :: (Sized b, Monoid b) =>
53 Int -> JoinList b a -> JoinList b a
55 takeJ n _ | n < 0 = Empty
57 takeJ n v@(Single _ _) | n == 0 = v
59 takeJ n v@(Append t l r) | n > getSize (size t) = v
60 | n < leftSize = takeJ n l
61 | otherwise = let rt = takeJ (n - leftSize) r in
62 Append ((tag l) `mappend` (tag rt)) l rt
63 where leftSize = getSize . size . tag $ l