
I had a situation where I had some related types that all had toString functions. Of course in Haskell, lists all have to be composed of values of exactly the same type, so instead of passing around lists of values with these related types, I created a polyvariadic function polyToString so that I could write: (polyToString value1 value2 value3 ... valueN) which would then become a list of strings: [toString value1, toString value2, ... , toString valueN] I finally figured out how to do this, but it was a bit harder to figure this out than I expected, and I was wondering if it might be possible to create a small utility library to help other developers do this. It seems to me that in the general case, we would be dealing with a Monoid rather than a list of strings. We could have a toMonoid function and then return polyToMonoid value1 value2 ... valueN = (toMonoid value1) `mappend` (toMonoid value2) 'mappend' ... (toMonoid valueN) So anyone who wanted to convert a bunch of values of different types to a Monoid could easily pass them around using polyToMonoid so long as they defined the appropriate toMonoid function. Basically, a generalised list. So I tried writing the following code but GHC said it had undecidable instances. Has this ever been done successfully? class Monoidable a where toMonoid :: Monoid r => a -> r polyToMonoid :: (Monoidable a, Monoid r) => a -> r polyToMonoid k = polyToMonoid' k mempty class PolyVariadic p where polyToMonoid' :: (Monoidable a, Monoid r) => a -> r -> p instance Monoid r => PolyVariadic r where polyToMonoid' k ss = (toMonoid k) `mappend` ss instance (Monoidable a, Monoid r) => PolyVariadic (a -> r) where polyToMonoid' k ss = (\a -> polyToMonoid' k (toMonoid a) `mappend` ss)