data Foo a
is defined like:
data Foo a where
Foo :: (Typeable a, Show a) => a -> Foo a
-- perhaps more constructors
instance Show a =
getFoo :: (Show a, Typeable a) => String -> Foo a
getFoo "five" = fiveFoo
getFoo "false" = falseFoo
If fiveFoo :: Foo Int
and falseFoo :: Foo Bool
, you're essentially asking for getFoo
to return a different type depending on what value you feed it at run-time. You can't do that. In Haskell, all types must be known at compile-time.
If all you want to be able to do is convert the thing to a string, why not just store it as a string in the first place? I'm guessing the answer is that this is actually a simplification of the real problem you're trying to solve...(?)