Search code examples
haskellderiving

Deriving instance Typeable with context


I am writing function set wor working with HTTP requests and need to create a set of Exceptions for handling failures. Here it is

data HStream ty => ErrorResponse ty = ErrorResponse (Response ty)
data HStream ty => HttpException ty = WrongURIException String | ConnException ConnError | RequestException (ErrorResponse ty)
instance HStream ty => Exception (HttpException ty)

where WrongURIException corresponds to malformed uri, ConnException to errors in TCP stack and RequestException to handle responses with non-2xx response codes. Before declaring instance Exception on line 3 I should derive Typeable but I'm lost in types. How should I it?


Solution

  • Might I suggest not doing that. Datatype contexts are bad in pretty much every way possible. There's a reason that they've been deprecated. If you really, really, want them, use GADTs.

    If you don't use contexts, this is trivial

     {-# LANGUAGE DeriveDataTypeable #-}
     import Data.Typeable
     import Data.Data
    
    
     data ErrorResponse ty = ErrorResponse (Response ty)
                           deriving(Data, Typeable, Show)
     data HttpResponse ty = WrongURIException String 
                          | ConnException ConnError
                          | RequestException (ErrorResponse ty)
                           deriving(Data, Typeable, Show)
     instance (Typeable ty, Show ty) => Exception (HttpException ty)
    

    In particular as of GHC 7.8 you can't make your own instances for Typeable and Data, so deriving is the correct way.