Tools for functor combinator-based program design
|Version on this page:||0.4.1.0|
|LTS Haskell 19.33:||0.4.1.0|
|Stackage Nightly 2022-03-17:||0.4.1.0|
|Latest on Hackage:||0.4.1.2|
Module documentation for 0.4.1.0
Introductory Blog Post / Hackage
Tools for working with functor combinators: types that take functors (or other indexed types) and returns a new functor that “enhances” or “mixes” them in some way.
The main functionality is exported in Data.Functor.Combinators, but more fine-grained functionality and extra combinators (some of them re-implementations for compatibility) are available in other modules as well.
The goal is to represent schemas, DSL’s, and computations (things like parsers, things to execute, things to consume or produce data) by assembling “self-evident” basic primitives and subjecting them to many different successive transformations and combiners. The process of doing so:
- Forces you to make explicit decisions about the structure of your computation type as an ADT.
- Allows you to retain isolation of fundamental parts of your domain as separate types
- Lets you manipulate the structure of your final computation type through normal Haskell techniques like pattern matching. The structure is available throughout the entire process, so you can replace individual components and values within your structure.
- Allows you to fully reflect the structure of your final computation through pattern matching and folds, so you can inspect the structure and produce useful summaries.
The main benefit of this library in specific is to allow you to be able to work with different functor combinators with a uniform and lawful interface, so the real functionality here is the wide variety of functor combinators from all around the Haskell ecosystem. This library does not provide the functor combinators, as much as it re-exports them with a unified interface. However, it does “fill in the matrix”, in a sense, of functor combinators in specific roles that are missing from the haskell ecosystem.
To jump into using it, import Data.Functor.Combinator. For a full introduction, check out the Functor Combinatorpedia, which goes in-depth into the motivation behind functor combinator-driven development, examples of the functor combinators in this library, and details about how to use these abstractions!
On the surface, functor-combinators look like it fills a similar space to effects systems and libraries like mtl, polysemy, freer-simple, or fused-effects. However, the functor combinator design pattern actually exists on a different level.
Functor combinator design patterns can be used to help build the structure of the data types and schemas that define your program/DSL. Once you build these nice structures, you then interpret them into some target context. This “target context” is the realm that libraries like mtl and polysemy can fill; functor combinators serve to help you define a structure for your program before you interpret it into whatever Applicative or Monad or effects system you end up using.
September 29, 2021
- All of the missing instances to the typeclasses added in 0.4 that I could remember.
- Variations of
gatherN1added with typeclass-based multi-arity functions.
- GHC 9.0 compatibility (@ocharles)
September 3, 2021
Finally add Data.Functor.Invariant.Inplicative and Data.Functor.Internative, with the typlecasses
Internative, the invariant versions of
Move Data.Functor.Invariant.DivAp and Data.Functor.Invariant.DecAlt to Data.Functor.Invariant.Inplicative.Free and Data.Functor.Invariant.Internative.Free, respectively.
rejectare now a part of the typeclasses.
concatDecAltfamily of functions generalized to work for all Inplicative and Inplus, respectively, and moved to the modules for their respective typeclasses as
Changed the order of arguments on
swerveto be consistent with the arguments of
Changed the order of arguments in the
Swervepatterns to be more consistent with the new order of arguments for
Changed the order of arguments in the
DecAlt1patterns to be more consistent with the order of arguments for
Night, using the
runDayis found in Data.Functor.Invariant.Inplicative, even though it should belong in Data.Functor.Invariant.Day, but that’s in a different package.
Night, in parallel to
Day. Uses the
datheris found in Data.Functor.Invariant.Inplicative, even though it should belong in Data.Functor.Invariant.Day, but that’s in a different package.
August 27, 2020
- Data.HFunctor.HTraversable added, providing
- Control.Monad.Freer.Church: Missing
Plusinstances added for
Compmade more kind-polymorphic
foldChain1Aadded, for effectful folding of chains.
August 15, 2020
DecAlt, to better reflect their abstracted nature ever since 0.3.4.0. The modules are renamed to Data.Functor.Invariant.DivAp and Data.Functor.Invariant.DecAlt.
v0.3.5.1: Fixed infinite recursion bug for Tensor instances of invariant
August 14, 2020
Data.HFunctor.Route: A new twist on getting invariant functor combinators. Instead of creating new ones, utilize existing functor combinators with
Data.Functor.Invariant.Day.Chain and Data.Functor.Invariant.Night.Chain created, factoring out the
Chainpart of the invariant
Night. This was done to fix the fact that Data.Functor.Invariant.Day is a module that already existed in kan-extensions. Oops!
- As a consequence,
NightChainare now newtype wrappers instead of plain type synonyms.
- As a consequence,
v0.3.4.1: Add in missing
ProPost, as well as a bunch of instances for
v0.3.4.2: Add in missing
August 11, 2020
- Control.Applicative.ListF: Missing contravariant instances added for
- Data.HFunctor: Add
injectContramap, two small utility functions that represent common patterns in injection and mapping.
- Data.Functor.Combinator: Replace
divideNand related functions with
dsum1, which is an altogether cleaner interface that doesn’t require heterogenous lists. A part of a larger project on cleaning up
- Data.Functor.Contravariant.Divise: Add useful utility functions
<:>, which makes the type of
divisecloser to that of
- Data.Functor.Contravariant.Divisible.Free: Implement
Divin terms of a list, instead of the mirrored
Ap. Should make it much easier to use, although a less-than-ideal
Coyonedais required to keep it compatible with the contravariant
Dayin kan-extensions. Added patterns to recover the original interface.
August 9, 2020
icollect1now are more constrained: they only work on things that have
Interpretinstances for all
AltConst m. While this doesn’t affect how it works on any types in this library, it does make the type signature a little more clean (hiding the usage of
DList) and prevents one from making an odd
Interpretinstance that does something weird with the
DList. This also allows us to drop the direct dlist >= 1.0 dependency.
bifanout1added as contravariant consumer versions of
bicollect1removed because they really don’t make sense for associative tensors, which can only have at most one of each tensor.
biapplyadded as the contravariant consumer version of
- Data.Functor.Invariant.Day: Add conversion functions from chains to the
- Data.Functor.Invariant.Night: Add conversion functions from chains to the
chainNonEmptyF. Also add “undescored” versions to the covariant versions,
chainNonEmptyF_, to more accurately represent the actual contravariant either-based day convolution. Also changed
August 7, 2020
collectImade more efficient, and renamed to
icollect, respectively, to mirror
collectIare left in with a deprecation warning.
icollect1added to ensure a non-empty collection.
AltConstadded to aid in implementation.
bicollect1added to ensure a non-empty collection. biget and bicollect made more efficient.
- Data.Functor.Contravariant.Night, Data.Functor.Invariant.Night:
refutedadded for a convenient
toChain1, respectively, to mirror
August 5, 2020
Data.HBifunctor.Associative, Data.HBifunctor.Tensor: Support for
Invariantfunctor combinators. Main change to the infrastructure: add a
FunctorByassociated constraint to
Associativeto signal what “sort of functor” the tensor supports: it should either be
Data.Functor.Contravariant.Divise, Data.Functor.Contravariant.Decide, and Data.Functor.Contravariant.Conclude: Temporarily add in the semigroupoidal contravariant typeclasses. These should only be needed until they get merged into semigroupoids.
Data.Functor.Contravariant.Divisible: Add free structures for contravariant typeclass hierarchy.
Added in some new day convolutions:
Night, a contravariant day convolution using
Either, which is the tensor that generates
Day, an invariant day convolution using tuples.
Night, an invariant day convolution using either.
For the invariant day convolutions, we could write free monoids on them (like
Dec). But instead we just outsource our free structures to
Chain, providing useful pattern synonyms and folding functions to pretend like we had an actual free structure.
Data.Functor.Combinator: Useful functions in for working with divisible and decidable contravariant functors:
Invariantinstances for many types.
FreeOfadjusted to allow for contravariant free types.
unsafeConclude, to mirror the situation with
November 11, 2019
Major restructuring of the hbifunctor-based classes.
Data.HBifunctor.Tensorare more or less completely rewritten; the typeclasses are restructured in order to more properly reflect the math that motivates them. See the updated type classes to see what methods ended up where.
However, much of the external API that is independent of the underlying abstraction is effectively unchanged (
For the most part, the migration would involve:
-MFas suffixes for function names now become
upgradeCno longer exists; use unsafe functions from Data.Functor.Combinator.Unsafe instead, on a per-tensor basis.
Interpret: It now takes an extra type parameter, the type to interpret into. This makes it more consistent with the new
SemigroupIn. Most of the external API should be effectively unchanged.
For the most part, the migration would only affect people who write instances of
Interpret. Instead of
instance Interpret MyType where type C MyType = Monad
you would write:
instance Monad f => Interpret MyType f where
July 13, 2019
- Moved to trivial-constraints-0.6.0.0
June 19, 2019
June 19, 2019
- Small tweaks for haddock generation and dependency bounds.
June 19, 2019
- Initial release