{-# LANGUAGE ExistentialQuantification #-}
-- This Foo can only be constructed with instances of Show as its argument.
data Foo a = forall a. Show a => Foo a
-- Note that there is no "Show a => ..." context here:
-- Foo itself already carries that constraint around with it.
instance Show (Foo a) where
show (Foo a) = show a
getFoo :: String -> Foo a
getFoo "five" = Foo 5
getFoo "false" = Foo False
main = print . getFoo =<< getLine