record-wrangler-0.1.1.0: Alter your records with ease

RecordWrangler

Description

This module contains a Template Haskell helper to produce a new datatype with modified field names. The initial use case is to allow for easier record construction with Lumi's databases models, which have record fields prefixed with an _, and the Stats records, which do not have this underscore. The use of a naming scheme convention allows one to write the conversion function as:

convertData (Entity id Old.Record{..}) RecordStats{..} =
Entity (coerce id) New.Record
{ ..
-- Some fields need massaging
, _recordClientId = coerce _recordClientId
-- Some fields don't need massaging, but need to be explicitly labeled.
, _recordStatsFoo = recordStatsFoo
}

where each field in RecordStats must be repeated. This can be accomplished fairly easily with a vim macro, but it's more fun and less error prone to write Haskell.

With this module, we can instead write:

wrangle ''RecordStats with { fieldLabelModifier = ('_' :) }

which generates a new type RecordStats' with the same fields, but modified to have different field labels. It also creates a conversion function. Now, we can write (with ViewPatterns):

convertData
(Entity id Old.Record{..})
(wrangleRecordStatsToRecordStats' -> RecordStats'{..})
=
Entity (coerce id) New.Record
{ ..
, _recordClientId = coerce _recordClientId
}

Now, the only terms that need to be mentioned are the ones that cause a compile-time error due to the types not matching up.

Synopsis

# The Wranglin One

Create a new datatype with altered field labels, type name, and constructor names along with a conversion function.

The conversion function will have a name matching the pattern:

wrangle + OldTypeName + To + NewTypeName

As an example, consider the following datatype and wrangling:

data Person = Person { name :: String, age :: Int }

'wrangle' ''Person 'with'
{ 'fieldLabelModifier' = ('_' :)
, 'typeNameModifier' = ("Powerful" ++)
}

This has the effect of creating this new datatype and function:

data PowerfulPerson = Person' { _name :: String, _age :: Int }

wranglePersonToPowerfulPerson :: Person -> PowerfulPerson
wranglePersonToPowerfulPerson (Person x0 x1) = Person' x0 x1

Since: 0.1.0.0

# The Options For Wranglin

The options for wrangling records. The constructor is hidden so that we can add new features and powers without breaking your code!

This is the default set of WrangleOpts. It affixes a ' character to the end of the fields, type, and constructor. If you want different behavior, then you will want to alter the fields:

wrangle ''Record defWrangleOpts { fieldLabelModifier = ('_' :) }


Since: 0.1.0.0

This function will be applied to every field label in the provided record.

Since: 0.1.0.0

This function will be applied to the constructor name.

Since: 0.1.0.0

This function will be applied to the type name.

Since: 0.1.0.0

Add the following fields to the datatype. These will be inserted afterwards, and will have *exactly* the name you provide - the fieldLabelModifier function *will not* be applied to this value.

field :: IsType typ => String -> typ -> NewField Source #

Add a new field to the given record. For simple types, you can simply pass in the name:

field "userName" ''String


If the type is more complicated than a single name, then you can use the type quasiquoter, like so:

field "userName" [t|Char -> Maybe String|]



since 0.1.1.0

data NewField Source #

A new field to add to the datatype. Use the function field to create values of this type.

Since: 0.1.1.0

data Proxy (t :: k) :: forall k. k -> Type #

Proxy is a type that holds no data, but has a phantom parameter of arbitrary type (or even kind). Its use is to provide type information, even though there is no value available of that type (or it may be too costly to create one).

Historically, Proxy :: Proxy a is a safer alternative to the 'undefined :: a' idiom.

>>> Proxy :: Proxy (Void, Int -> Int)
Proxy


Proxy can even hold types of higher kinds,

>>> Proxy :: Proxy Either
Proxy

>>> Proxy :: Proxy Functor
Proxy

>>> Proxy :: Proxy complicatedStructure
Proxy


Constructors

 Proxy
Instances