Posted on September 1, 2020

Why Template Haskell?

Among other thigs, it can generate boilerplate for you, so that you spend time on more important things.

Let’s say we have the following datatypes:

data Project
  =  Project
     {
       name      :: String
     , resx      :: Int
     , resy      :: Int
     , _models   :: [Model]
     , _textures :: [Texture]
     , _cameraP  :: [Float]
     } deriving Show
	 
data Model
  =  Model
     {
       _path :: String
     } deriving Show

data Texture
  =  Texture
     {
       _path :: String
     } deriving Show

If we wanted, we could write JSON interfaces for it like this:

instance FromJSON Project where
  parseJSON (Object o) =
    Project
      <$> ((o .: "project") >>= (.: "name")) 
      <*> ((o .: "project") >>= (.: "resx"))
      <*> ((o .: "project") >>= (.: "resy"))
      <*> ((o .: "project") >>= (.: "models"))
      <*> ((o .: "project") >>= (.: "textures"))
      <*> ((o .: "project") >>= (.: "camera"))
  parseJSON _ = mzero

instance FromJSON Model where
  parseJSON (Object o) =
    Model
      <$> o .: "path"
  parseJSON _ = mzero

instance FromJSON Texture where
  parseJSON (Object o) =
    Texture
      <$> o .: "path"
  parseJSON _ = mzero

Thanks to TH, we can write like this instead:

deriveJSON defaultOptions ''Project

deriveJSON defaultOptions ''Model

deriveJSON defaultOptions ''Texture

Both are equivalent.

Cheers, Vlad.

comments powered by Disqus