
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.