origami-0.0.1: A framework for transforming heterogenous data through folds

Safe HaskellNone
LanguageHaskell2010

Data.Origami.Internal.Build

Contents

Description

Builds fold declarations for a FoldFamily.

Synopsis

Documentation

buildFolds Source

Arguments

:: [Name]

names of the root datatypes

-> [Name]

names of the n-ary functor classes to be used

-> [Name]

names of datatypes declared to be atomic

-> Q [Dec] 

First discovers the fold family by starting at the root datatypes and including their components' datatypes recursively, then builds declarations from it to be spliced into the source file.

Datatypes declared as atomic will not be recursed into and will not become part of the fold family.

In general, the framework does not currently handle parameterized types, but applications of Traversable, Bitraversable, or Tritraversable can be handled, if the user declares them. The n-ary functors are treated as "transparent" and traversed through. (You are not expected to understand this explanation: take a look at the type signatures in the Haddock of the generated code.)

The framework:

  • Generates a parameterized Fold record; each parameter xxx corresponds to a non-atomic datatype Xxx in the fold family. Each field mkYyy of the Fold corresponds to a constructor Yyy used by some datatype in the fold family.
  • Generates an idFold record; folding over idFold is equivalent to applying id: it does nothing. idFold is useful as a base record to build your own folds upon.
  • Generates an errFold function to create a tagged Fold record, with undefined fields that give a useful error message when accessed. mkXxx (errFold "example") is defined as error "example.mkXxx".
  • Generates a monadicFold function that transforms a Fold into one that applies the base fold monadically in a bottom-up, left-to-right way. (Again, see the Haddocks of the generated code.)
  • For each datatype Xxx, generates a foldXxx function that applies a Fold to an Xxx value, returning a value of type xxx.

The names Fold, idFold, errFold, and monadicFold are fixed. They are intended to be imported qualified.

There are other restrictions not mentioned here: if you hit any of them, the framework should output a helpful, intelligible error message when generating the declarations before trying to splice and compile declarations. You should see no errors from the compiler trying to compile bad generated code.

buildFoldsDryRun :: [Name] -> [Name] -> [Name] -> Q [Dec] Source

Prints onto standard output the result of running buildFolds but doesn't splice the fold declarations.

for testing

data BuildErr Source

Errors possible while building a FoldFamily

buildFoldFamilyMaybe :: [Name] -> [Name] -> [Name] -> Q Exp Source

Builds a FoldFamily or returns an error. Spliced result is of type Either BuildErr FoldFamily.