'Haskell - types and if statements

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.



Solution 1:[1]

I will answer the question as it is. Haskell erases all type information during compile time, mostly for efficiency reasons. By default, when a polymorphic function is called, e.g. f :: a->a, no type information is available, and f has no way to know what a actually is -- in this case, f can only be the identity function, fail to terminate, or raise an error.

For the rare cases where type information is needed, there is Typeable. A polymorphic function having type f :: Typeable a => ... is passed a run-time description of the type a, allowing it to test it. Essentially, the Typeable a constraint forces Haskell to keep the runtime information until run time. Note that such type information must be known at the call site -- either because f is called with a completely known type, or because f is called with a partially known type (say f x with x :: Maybe b) but there are suitable Typeable constraints in scope (Typeable b, in the previous example).

Anyway, here's an example:

{-# LANGUAGE TypeApplications, ScopedTypeVariables, GADTs #-}

import Data.Typeable

tostring :: forall b. (Show b, Typeable b) => b -> String
tostring x = case eqT @b @String of  -- if b==String
   Just Refl -> x                    -- then
   Nothing   -> show x               -- else

Note how we were able to return x in the "then" branch, since there it is known to be a String.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 chi