Here you can use viewing templates, this is a pretty convenient extension.
{-# LANGUAGE ViewPatterns #-}
import Data.Data
data Foo = Bool Bool | Int Int | Double Double
deriving (Show)
foo :: Typeable a => a -> Foo
foo (cast -> Just x) = Int x
foo (cast -> Just x) = Bool x
foo (cast -> Just x) = Double x
foo _ = error "i dunno"
Results:
* Main>: l foo_typeable.hs
[1 of 1] Compiling Main (foo_typeable.hs, interpreted)
Ok, modules loaded: Main.
* Main> foo "123"
*** Exception: i dunno
* Main> foo 1
*** Exception: i dunno
* Main> foo (1 :: Int)
Int 1
* Main> foo (1 :: Integer)
*** Exception: i dunno
*Main> foo (1 :: Double)
Double 1.0