Implementing `dropJ` to Drop `JoinList` Elements In the same vein as the (+++) function on JoinList and indexJ on JoinList, I implemented dropJ to drop elements from a JoinList.

Here's my attempt:

dropJ ::(Sized b, Monoid b) =&gt; Int -&gt; JoinList b a -&gt; JoinList b a
dropJ _ Empty = Empty
dropJ i jl | i &lt;= 0           = jl
dropJ _ (Single _ _)          = Empty
dropJ i (Append _ left right) 
  | i &gt;= leftHt               = dropJ (i-leftHt) right
  | otherwise                 = dropJ i left
    where leftHt = (getSize. size . tag) left


Testing

*JoinList&gt;jlIndex2
Append (Size 3) 
               (Single (Size 1) "foo") 
               (Append (Size 2) 
                   (Single (Size 1) "bar") 
                   (Single (Size 1) "baz"))

*JoinList&gt; dropJ 1 jlIndex2
Append (Size 2) (Single (Size 1) "bar") (Single (Size 1) "baz")

*JoinList&gt; dropJ 2 jlIndex2
Single (Size 1) "baz"

*JoinList&gt; dropJ 3 jlIndex2
Empty

*JoinList&gt; dropJ 0 jlIndex2
Append (Size 3) 
               (Single (Size 1) "foo") 
               (Append (Size 2) 
                   (Single (Size 1) "bar") 
                   (Single (Size 1) "baz"))
It's fine, but you have a bug in the Append case, as you completely disregard the right part of the tree:

dropJ i (Append _ left right) 
  | i &gt;= leftHt               = dropJ (i-leftHt) right
  | otherwise                 = dropJ i left              -- where is right?
    where leftHt = (getSize. size . tag) left


You can fix this if you use +++ here again:

dropJ i (Append _ left right) 
  | i &gt;= leftHt               = dropJ (i-leftHt) right
  | otherwise                 = dropJ i left +++ right
    where leftHt = (getSize. size . tag) left


Other than that we could argue about formatting, but your code is fine. It works. Note that you should add more test cases though. A Arbitrary a =&gt; Gen (JoinList m a) generator might come in handy for QuickCheck, but that's left as an exercise.