Is there a good way to use type information to choose to do different things?
For example, this isn't valid Haskell, but I don't see why it couldn't be:
tostring :: (Show b) => b -> String
tostring x = f x where f = if b == String then tail . init . show else show
The important part is not getting the correct string out, but using the type of b
as a way to switch between functionality/functions.
@chi's answer already demonstrates how to use Typeable
to do run-time type checking, but I'd like to point out that to me, this looks like exactly the thing typeclasses are meant for. For your example, the only problem is that you don't like the Show
implementation for String
: In that case, just create your own typeclass!
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE UndecidableInstances #-}
-- The class
class MyShow a where
myShow :: a -> String
-- The instance for String
-- (The `OVERLAPPING` pragma is required, because
-- otherwise GHC won't know which instance to choose for String)
instance {-# OVERLAPPING #-} MyShow [Char] where
myShow = tail . init . show
-- For everything that is not a String, just copy the Show instance
instance Show a => MyShow a where
myShow = show
EDIT: As pointed out by leftaroundabout, overlapping instances are complicated and can lead to some unexpected behavior. Look at the example at the bottom of the documentation.