sepp2k already provided a good answer, but let me take a similar but slightly different angle. What you did is result type polymorphism. You wrote:
listFree :: Foldable f => a -> f Int
This means that you can create any folding that the user may need. Of course, you could never fulfill this promise because Foldable does not provide any constructor-like functions.
So what are you trying to do with generics. You want to make weak promises: the listFree function will produce some Foldable , but it may change in the future. You can implement it using a regular list today, but later you can re-implement it with something else. And you want this implementation detail to be just that: implementation detail. You want the contract for this function (type signature) to remain the same.
Sounds like work for another weird and confusing Haskell extension! Existential quantification!
{-
Here I specify the value of foo , but it is of type SomeFoldable Int . I am not telling you that it is t21, just that it is some kind of folding. SomeFoldable can easily be made a Foldable instance for convenience.
instance Foldable SomeFoldable where fold (F xs) = fold xs foldMap f (F xs) = foldMap f xs foldr step z (F xs) = foldr step z xs foldl step z (F xs) = foldl step z xs foldr1 step (F xs) = foldr1 step xs foldl1 step (F xs) = foldl1 step xs
Now we can do Foldable things with foo , for example:
> Data.Foldable.sum foo 6
But we can do nothing with this, except that Foldable provides:
> print foo No instance for (Show (SomeFoldable Int)) blah blah blah
Easily adapt your code to work as you wish:
data Struct = Struct main = do print $ foldr (+) 0 $ list Struct print $ foldr (+) 0 $ listFree Struct listFree :: a -> SomeFoldable Int listFree s = F [10] class TestClass a where list :: a -> SomeFoldable Int instance TestClass Struct where list s = F [10]
But remember, existential quantification has its drawbacks. Unable to deploy SomeFoldable to get Foldable concrete Foldable . The reason for this is the same reason that your function signature was incorrect at the beginning: it promises a polymorphism of the result type: a promise that it cannot keep.
unwrap :: Foldable f => SomeFoldable a -> fa -- impossible! unwrap (F xs) = xs -- Nope. Keep dreaming. This won't work.