I want to implement a generic function which will try to convert any type to a list. I’ve tried to achieve this with the help of Typeable:
import Data.Data
import Data.Foldable
import Control.Applicative
asFoldable :: (Typeable (a b), Foldable z, Typeable (z b)) => a b -> Maybe (z b)
asFoldable = cast
asList :: (Typeable1 a, Typeable b) => a b -> Maybe [b]
asList x = Data.Foldable.foldr (:) [] <$> asFoldable x
The code above compiles just fine without the asList definition, but with it, it keeps barking on the ambiguousness of the t0 type variable, referring to the a I guess. Now I’ve tried to trick around with it but it only works when I specify the specific types for the cast like Maybe [String] or Maybe (Set String) and etc.
My guess is that I got to fool the compiler with the asFoldable type declaration, but it still wouldn’t work because it doesn’t support casting to typeclasses. Is this true? Is there a better way to try to convert any type to a list? Is there any at all?
There is no way (without Template Haskell, and that’s almost always overkill) to test for presence of an instance of a type class dynamically. The right way to convert arbitrary structures to other arbitrary structures in a generic manner is to use
Data.Data, which is the generics that @hammar was talking about in your other question.Of course, as @hammar also said, you may want to treat lists and strings differently.