Search code examples
haskelltypesinstancederiving

Haskell Typeable instance


I'm using cmdargs to get some arguments from a command line program. I'm using some special type in my program

data Function = Max
              | Min
              | Moy
              | Med
              deriving (Eq,Data,Typeable)

I can pass these types directly in arguments with "Max" "Min" "Moy" "Med" by deriving the Function datatype in the classes Data and Typeable. My problem is my program is becoming more complex and I need to rename my constructor to avoid name collisions.

data Function = funMax
              | funMin
              | funMoy
              | funMed
              deriving (Eq,Data,Typeable)

However, I would like to keep accessing these constructor with "Max" "Min" "Moy" "Med". To do that, I suppose I need to create my own Data and Typeable Instances of Function, is that right ?

My problem is I didn't manage to create these instance even after reading the Hackage documentation.

Have you ever succesfully created Data and Typeable instances of your own data type?


Solution

  • In recent versions of GHC, Typeable simply cannot be user-defined. Its casting operations are supposed to be guaranteed safe, and for that only automatically derived instances are allowed.

    Since GHC 7.10, it's changed further: Typeable is now automatically derived for all types, so deriving Typeable is actually redundant (but may be included for backwards compatibility.)

    Data can still be user-defined, but I'm not sure it's a good idea. In fact for your use case I'm suspecting it would be better to use the much simpler Read class instead.

    You can also avoid renaming your constructors by splitting them off into a different module, and importing that qualified:

    module Types.Fun where
    data Function = Max
                  | Min
                  | Moy
                  | Med
                  deriving (Eq,Data,Typeable)
    
    ...
    
    module Main where
    import qualified Types.Fun as Fun
    
    ... case ... of Fun.Max -> ...