sum-type-boilerplate: Library for reducing the boilerplate involved with sum types

[ library, mit, th, types ] [ Propose Tags ]

Library for reducing the boilerplate involved in creating and manipulating sum types


[Skip to Readme]
Versions [faq] 0.1.0, 0.1.1
Change log CHANGELOG.md
Dependencies base (>=4.9 && <5), template-haskell [details]
License MIT
Author David Reaver
Maintainer David Reaver
Category Types, TH
Home page https://github.com/jdreaver/sum-type-boilerplate#readme
Bug tracker https://github.com/jdreaver/sum-type-boilerplate/issues
Source repo head: git clone https://github.com/jdreaver/sum-type-boilerplate
Uploaded by jdreaver at Mon May 29 17:12:30 UTC 2017
Distributions LTSHaskell:0.1.1, NixOS:0.1.1, Stackage:0.1.1
Downloads 851 total (43 in the last 30 days)
Rating (no votes yet) [estimated by rule of succession]
Your Rating
  • λ
  • λ
  • λ
Status Hackage Matrix CI
Docs available [build log]
Last success reported on 2017-05-29 [all 1 reports]

Modules

[Index]

Downloads

Maintainer's Corner

For package maintainers and hackage trustees


Readme for sum-type-boilerplate-0.1.0

[back to package description]

sum-type-boilerplate: A Haskell sum type library

CircleCI

This library allows users to use Template Haskell to easily construct and manipulate sum types. It was born out of the author's desire to reduce the boilerplate associated with sum types while keeping the type safety they provide.

Sum Types

A sum type (also called a tagged union) looks like this in Haskell:

data MySum
  = MySumTypeA TypeA
  | MySumTypeB TypeB
  | MySumTypeC TypeC

Constructing this when you have a large number of types can be error-prone if you intend to have a uniform naming scheme, and if you intend to only have each type present once.

If you have many sum types with overlapping sets of types, then functions to convert between them can be full of boilerplate.

data OtherSum
  = OtherSumTypeA TypeA
  | OtherSumTypeB TypeB

otherSumToMySum :: OtherSum -> MySum
otherSumToMySum (OtherSumTypeA typeA) = MySumTypeA typeA
otherSumToMySum (OtherSumTypeB typeB) = MySumTypeB typeB

mySumToOtherSum :: MySum -> Maybe OtherSum
mySumToOtherSum (MySumTypeA typeA) = Just $ OtherSumTypeA typeA
mySumToOtherSum (MySumTypeB typeB) = Just $ OtherSumTypeB typeB
mySumToOtherSum other = Nothing

The boilerplate in examples isn't too bad, but consider writing this when your sum type has dozens of types in it!

Where does this library come in?

Using sum-type-boilerplate, you can reduce all of the previous code into the following:

constructSumType "MySum" defaultSumTypeOptions [''TypeA, ''TypeB, ''TypeC]
constructSumType "OtherSum" defaultSumTypeOptions [''TypeA, ''TypeB]
sumTypeConverter "otherSumToMySum" ''OtherSum ''MySum
partialSumTypeConverter "mySumToOtherSum" ''MySum ''OtherSum

More features

  • This library has an extremely simple implementation. (In fact, it is useful as an example if you are learning template-haskell for the first time.)
  • The only dependency is on template-haskell. That means adding it as a dependency probably doesn't introduce transitive dependencies.
  • The template haskell used here just produces vanilla Haskell data types. No crazy type-level magic is going on. That means if you want to ditch this library later on, just copy the generated code into your project.