Hi,

unflt was a poor choice of name. flt2, which flattens a datatype containing a flattenable datatype, would have been a better name.

If I was making a flatten class, I wouldn't want Monad as a constraint
on the result container. Monad doesn't really say anything about
"containers" - there are some containers that are Monads, but there
are monads that aren't containers and there are containers that aren't
monads.

You're right. My initial class was

class Monoid m => t -> m where
   flt :: t -> m

instance (Tree a) [a] where flt = fltTree
instance (Maybe a) [a] where flt = maybeToList

for some tree type like `data Tree a = Nil | Node a (Tree a) (Tree a)` (for simplicity). The problem is that I couldn't figure out how to type the "flatten twice" function, which required a declaration like

flt2 :: (F t' m) => t' t -> m

which is clearly incorrect (since it gives rise to a kind mismatch). "Monad" and "Functor" were introduced just to get the definition of unflt to work, and was unsatisfactory.

I need to be able to assert that flt2 is a nested flattenable datatype, and that the return type of the nested and containing datatype is the same monoid. I can't figure out how to type this, however.