Skip to content
Switch branches/tags

Latest commit


Git stats


Failed to load latest commit information.
Latest commit message
Commit time


Build Status

This package uses TemplateHaskell to alter records in ways that may be convenient for you.


Let's say you've got a set of API types and a set of domain types. The API types define your HTTP contract, and you generically derive ToJSON and FromJSON instances from their field labels. They look like this:

data User = User
    { id :: Int
    , name :: String
    , age :: Int

data Dog = Dog
    { id :: Int
    , name :: String
    , toy :: FavoriteToy
    , ownerId :: Int

The domain types for your business logic look a little different, though. The record fields are prefixed with an _ underscore character, to allow for lens derivation. We can pretend they have other differences that are relevant to internal details and irrelevant for showing off record-wrangler if that makes you feel better.

data Dog = Dog
    { _id :: Int
    , _name :: String
    , _toy :: FavoriteToy
    , _ownerId :: Int

makeLenses ''Dog

data User = User
    { _id :: Int
    , _name :: String
    , _age :: Int

makeLenses ''User

If the record fields were the same, then we could just write the conversion function using RecordWildCards and it'd be fine:

convertUser Api.User{..} = Domain.User{..}

However, because the field labels are different, we have to do it manually:

convertUser Api.User{..} = Domain.User
    { _id = id
    , _name = name
    , _age = age 

This is annoying and boilerplatey. I don't know about you, but I hate writing code, for every line of code I write is a chance to mess up. Let's use record-wrangler to make these conversions easier.

wrangle ''Api.User defWrangleOpts 
    { fieldLabelModifier = \fieldStr -> '_' : fieldStr 

This is going to take the Api.User type and modify it slightly. By default, we append a ' to the constructor name, type name, and field labels. Here, we've decided to prepend a _ character to the field label. It also generates a function wrangleUserToUser' which converts the old record to the modified one.

With the power of view patterns, our conversion function is now quite concise:

convertUser :: Api.User -> Domain.User
convertUser (wrangleUserToUser' -> User'{..}) = Domain.User{..}


Alter datatypes at your leisure!




No releases published


No packages published