Well there are a few issues with doing this.
It's broken. typeOf
isn't supposed to be strict in it's argument so typeOf (undefined :: Char)
should work.
It's unsafe. Actually, if you manually create an instance of Typeable
you won't compile under Safe Haskell.
Keeping this in mind!
{-
import Data.Typeable
data C = C deriving (Typeable)
data D = D deriving (Typeable)
data E = E deriving (Typeable)
newtype Foo = Foo Char
instance Typeable Foo where
typeOf (Foo 'a') = typeOf (undefined :: C)
typeOf (Foo 'b') = typeOf (undefined :: C -> D)
typeOf (Foo 'c') = typeOf (undefined :: D -> E)
typeOf _ = typeOf (undefined :: String)
Now as an example of why this is terrible, consider
what :: Char -> C
what c = if isJust weird then fromJust weird else error "Sanity!"
where weird = fromDynamic . toDyn $ Foo c
Now
> what 'a'
C
> what 'b'
*** Exception: Sanity!
Depending on the representation of how Foo
this could do all sorts of fun things, like seg fault, spew nonsense answers, or make monkeys fly out of your ears.
Robert Harper gave a more dramatic example
{-
import Control.Exception
import Data.Typeable
newtype Foo = Foo (() -> IO ())
{- set Foo’s TypeRep to be the same as ErrorCall’s -}
instance Typeable Foo where
typeOf _ = typeOf (undefined :: ErrorCall)
instance Show Foo where show _ = ""
instance Exception Foo
main = Control.Exception.catch (error "kaboom") (\ (Foo f) -> f ())
Which gives
<interactive>: internal error: stg_ap_v_ret
(GHC version 7.6.3 for x86_64_unknown_linux)
Please report this as a GHC bug: http:
C-c C-c
Process haskell aborted (core dumped)