Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

GHC.Generics or Data.Data?

There are currently 2 (3 if you count TemplateHaskell) options for generic programming using GHC, Data.Data / Data.Typeable and GHC.Generics, both available from the base package. So, what are the advantages and disadvantages of each? Is GHC.Generics the "modern" way and Data.Data obsolete and just kept for backwards compatibility?

like image 512
bennofs Avatar asked Jul 06 '13 11:07

bennofs


People also ask

What is GHC generics?

The Generic and Generic1 type classesfrom and from1 map values of data types to their generic representations. Rep and Rep1 are associated type functions (the feature is a part of the TypeFamilies GHC extension) that take the type of data we want to manipulate and yield the type of its representation.

Does Haskell have generics?

Datatype-generic programming, also frequently just called generic programming or generics in Haskell, is a form of abstraction that allows defining functions that can operate on a large class of datatypes.


1 Answers

GHC.Generics is the modern way and it is much faster than SYB. It however exposes a different approach to generic programming to the end user, so I don't think that it should be thought of as a direct replacement of SYB, though it does solve the same problems.

A good example of how those approaches differ from user's perspective can be extracted from the aeson library's functionality of serialization of a record to JSON:

Without generics

{-# LANGUAGE OverloadedStrings #-} import Data.Aeson  data Coord = Coord { x :: Double, y :: Double }  instance ToJSON Coord where    toJSON (Coord x y) = object ["x" .= x, "y" .= y] 

And use toJSON of ToJSON typeclass afterwards.

Using GHC.Generics

{-# LANGUAGE DeriveGeneric #-} import Data.Aeson     import GHC.Generics  data Coord = Coord { x :: Double, y :: Double } deriving Generic  instance ToJSON Coord 

And use the same toJSON of ToJSON typeclass afterwards.

Using SYB

{-# LANGUAGE DeriveDataTypeable #-} import Data.Data import Data.Aeson.Generic  data Coord = Coord { x :: Double, y :: Double } deriving (Data, Typeable) 

And use a specific toJSON from Data.Aeson.Generic with the following signature:

toJSON :: Data a => a -> Value 
like image 181
Nikita Volkov Avatar answered Sep 20 '22 20:09

Nikita Volkov