Implementing (+++) to Join JoinList's
(I didn't know about the other JoinList questions when I was answering the other one one you asked.)

The case

(+++) left@(Single _ _)   right@(Single _ _)   =
  Append (tag $ Append mempty left right) left right


is redundant. There is no need to distinguish this case, also there is no need to call tag on a temporarily created Append value. Other than that, it looks good.

Just a remark, using Product with JoinList probably isn't very meaningful, monoids that provide useful information (depending on the use-case) would be Sum, Min or Max.

For testing, I'd suggest you to study QuickCheck. It allows you to define properties of your operations and automatically test them for various inputs. It's important to define good properties, in particular they should be distinct from the implementation of your operations. For example, you might want to test: For any JoinLists xs and ys


if i &lt; sizeJ xs then indexJ i (xs +++ ys) === indexJ i xs
if i &gt;= sizeJ xs then indexJ i (xs +++ ys) === indexJ (i - sizeJ xs) ys


etc.