wiki:NewtypeDeriving

Version 4 (modified by john@…, 8 years ago) (diff)

--

Generalised deriving for newtype

See ExtensionDescriptionHowto for information on how to write these extension descriptions. Please add any new extensions to the list of HaskellExtensions.

Brief Explanation

The deriving clause on a newtype can list any class. For any class except Read, Show, Typeable or Data, the instance is "the same" as for the wrapped type.

Examples

one area where this is particularly useful is when dealing with monad transformers. for example the jhc typechecking monad is declared as follows

data TcEnv = TcEnv { ... }

newtype TI a = TI (ReaderT TcEnv IO a)
    deriving(Monad,MonadFix,MonadIO,MonadReader TcEnv,Functor) 

and we end up with a complete monad with every interesting instance defined for free.

It is also good for selectively hiding properties of monad transformers

-- | Unique integer generator monad transformer.
newtype UniqT m a = UniqT (StateT Int m a)
    deriving(Monad,MonadTrans, Functor, MonadFix, MonadPlus)  

notice that while it uses a state transformer internally, the MonadState? class is intentionally left out of the deriving clause. this means that calls to the state monad will pass through the UniqT making stacking monads signifigantly easier.

A quick survey shows 34 different special purpose monads created in this fashion in jhc. This technique would not be possible without newtype deriving.

References

Pros

  • saves on repetitious boilerplate, significantly lowering the cost of newtype

Cons

  • difficult to specify without saying "the same representation"