The bookkeeper package

This is a package candidate release! Here you can preview how this package release will appear once published to the main package index (which can be accomplished via the 'maintain' link below). Please note that once a package has been published to the main package index it cannot be undone! Please consult the package uploading documentation for more information.


Please see for more information and examples.

[Skip to ReadMe]


Versions0.1.0.0,,,,,,, 0.2.3, 0.2.4, 0.2.5, 0.2.5
Dependenciesbase (>=4.9 && <4.11), bookkeeper, data-default-class, markdown-unlit, type-level-sets [details]
Copyright(c) Julian K. Arni
AuthorJulian K. Arni
CategoryData Structures, Records
Home page
Bug tracker
Source repositoryhead: git clone
UploadedSun Dec 17 21:08:05 UTC 2017 by aminb




Maintainers' corner

For package maintainers and hackage trustees

Readme for bookkeeper-0.2.5

[back to package description]

Bookkeeper Build Status

Bookkeeper is a new Haskell library that uses the new OverloadedLabels feature of GHC 8 to provide a new take on datatypes and records:

{-# LANGUAGE DataKinds #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE OverloadedLabels #-}
import Bookkeeper

jane :: Book '[ "name" :=> String, "age" :=> Int ]
jane = emptyBook
     & #name =: "Jane"
     & #age =: 30

-- >>> jane
-- Book {age = 30, name = "Jane"}
-- >>> jane ?: #name
-- "Jane"

It bears some similarities to Nikita Volkov's record library, but requires no Template Haskell.

Accesing a field that does not exist is a type error, made nicer with GHCs new custom type errors:

 -- >>> jane ?: #address
--   • The provided Book does not contain the field "address"
--     Book type:
--     '["age" ':-> Int, "name" ':-> String]

The order in which fields are inserted or appear in types does not matter. That is, in:

-- type A = Book '[ "field1" :=> Int,  "field2" :=> Bool]
-- type B = Book '[ "field2" :=> Bool, "field1" :=> Int ]

Types A and B are the same.

You can set, modify, or get fields. See the haddocks for more information.

main :: IO ()
main = return ()