functor-combinators
Tools for functor combinator-based program design
https://github.com/mstksg/functor-combinators#readme
LTS Haskell 23.1: | 0.4.1.3 |
Stackage Nightly 2024-12-27: | 0.4.1.3 |
Latest on Hackage: | 0.4.1.3 |
functor-combinators-0.4.1.3@sha256:4756ec042170ae3982e875e71c0a7542c4b7ddc59f649da57adf1b7d4bda19cb,5692
Module documentation for 0.4.1.3
- Control
- Control.Applicative
- Control.Monad
- Control.Monad.Freer
- Control.Natural
- Data
- Data.Functor
- Data.Functor.Apply
- Data.Functor.Combinator
- Data.Functor.Contravariant
- Data.Functor.Invariant
- Data.HBifunctor
- Data.HFunctor
- Data.Functor
functor-combinators
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!
Comparisons
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.
Changes
Changelog
Version 0.4.1.3
January 9, 2024
https://github.com/mstksg/functor-combinators/releases/tag/v0.4.1.3
- Compatibility with transformers 0.6, and therefore ghc 9.6 (#7)
Version 0.4.1.2
January 29, 2023
https://github.com/mstksg/functor-combinators/releases/tag/v0.4.1.2
- Add Invariant instances to Freer.Church types
Version 0.4.1.1
January 29, 2023
https://github.com/mstksg/functor-combinators/releases/tag/v0.4.1.1
- Fix builds and warnings for GHC 9.2 and base 4.16
Version 0.4.1.0
September 29, 2021
https://github.com/mstksg/functor-combinators/releases/tag/v0.4.1.0
- All of the missing instances to the typeclasses added in 0.4 that I could remember.
- Variations of
concatInply
/concatInplicative
/concatInalt
/concatInplus
renamed togatheredN
/swervedN
/gatheredN1
/swervedN1
. gatherN
,gatherN1
added with typeclass-based multi-arity functions.- GHC 9.0 compatibility (@ocharles)
Version 0.4.0.0
September 3, 2021
https://github.com/mstksg/functor-combinators/releases/tag/v0.4.0.0
-
Finally add Data.Functor.Invariant.Inplicative and Data.Functor.Internative, with the typlecasses
Inply
,Inplicative
,Inalt
,Inplus
, andInternative
, the invariant versions ofApply
/Divise
,Applicative
/Divisible
,Alt
/Decide
,Plus
/Choose
, andAlternative
/Decidable
. -
Move Data.Functor.Invariant.DivAp and Data.Functor.Invariant.DecAlt to Data.Functor.Invariant.Inplicative.Free and Data.Functor.Invariant.Internative.Free, respectively.
Their specialized
gather
/knot
/swerve
/reject
are now a part of the typeclasses. -
concatDivAp
family andconcatDecAlt
family of functions generalized to work for all Inplicative and Inplus, respectively, and moved to the modules for their respective typeclasses asconcatInplicative
,concatInply
,concatInplus
, andconcatInalt
. -
Changed the order of arguments on
gather
andswerve
to be consistent with the arguments ofinvmap
,Day
, andNight
. -
Changed the order of arguments in the
Gather
, andSwerve
patterns to be more consistent with the new order of arguments forgather
/swerve
. -
Changed the order of arguments in the
DivAp1
andDecAlt1
patterns to be more consistent with the order of arguments forDay
andNight
. -
Add
runDay
andrunNight
for invariantDay
andNight
, using theInply
andInalt
typeclasses, respectively.runDay
is found in Data.Functor.Invariant.Inplicative, even though it should belong in Data.Functor.Invariant.Day, but that’s in a different package. -
Add
dather
,necide
, andnerve
to invariantDay
, contravariantNight
, invariantNight
, in parallel todap
for covariantDay
. Uses theInply
,Divise
, andInalt
typeclasses, respectively.dather
is found in Data.Functor.Invariant.Inplicative, even though it should belong in Data.Functor.Invariant.Day, but that’s in a different package. -
Add
hfor
andhfor1
to Data.HFunctor.HTraversable.
Version 0.3.6.0
August 27, 2020
https://github.com/mstksg/functor-combinators/releases/tag/v0.3.6.0
- Data.HFunctor.HTraversable added, providing
HTraversable
andHTraversable1
. - Control.Monad.Freer.Church: Missing
Apply
,Alt
, andPlus
instances added forComp
. - Data.HBifunctor:
HFunctor
instances forLeftF
,RightF
,Joker
,Void3
, andComp
made more kind-polymorphic - Data.HFunctor.Interpret:
itraverse
added, mimickinghtraverse
for properInterpret
instances. - Data.HFunctor.Chain:
foldChainA
andfoldChain1A
added, for effectful folding of chains.
Version 0.3.5.0
August 15, 2020
https://github.com/mstksg/functor-combinators/releases/tag/v0.3.5.0
-
DayChain
andNightChain
renamed toDivAp
andDecAlt
, 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
Day
/Night
.
Version 0.3.4.0
August 14, 2020
https://github.com/mstksg/functor-combinators/releases/tag/v0.3.4.0
-
Data.HFunctor.Route: A new twist on getting invariant functor combinators. Instead of creating new ones, utilize existing functor combinators with
Pre
/Post
. -
Data.Functor.Invariant.Day.Chain and Data.Functor.Invariant.Night.Chain created, factoring out the
Chain
part of the invariantDay
/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,
DayChain
andNightChain
are now newtype wrappers instead of plain type synonyms.
- As a consequence,
-
v0.3.4.1: Add in missing
Functor
andInvariant
instances forProPre
andProPost
, as well as a bunch of instances forProPre
. -
v0.3.4.2: Add in missing
HFunctor
,Inject
,Interpret
instances forPostT
.
Version 0.3.3.0
August 11, 2020
https://github.com/mstksg/functor-combinators/releases/tag/v0.3.3.0
- Control.Applicative.ListF: Missing contravariant instances added for
MaybeF
. - Data.HFunctor: Add
injectMap
andinjectContramap
, two small utility functions that represent common patterns in injection and mapping. - Data.Functor.Combinator: Replace
divideN
and related functions withdsum
anddsum1
, which is an altogether cleaner interface that doesn’t require heterogenous lists. A part of a larger project on cleaning upDivisible
tools. - Data.Functor.Contravariant.Divise: Add useful utility functions
dsum
and<:>
, which makes the type ofdivise
closer to that of<|>
andasum
. - Data.Functor.Contravariant.Divisible.Free: Implement
Div
in terms of a list, instead of the mirroredAp
. Should make it much easier to use, although a less-than-idealCoyoneda
is required to keep it compatible with the contravariantDay
in kan-extensions. Added patterns to recover the original interface.
Version 0.3.2.0
August 9, 2020
https://github.com/mstksg/functor-combinators/releases/tag/v0.3.2.0
- Data.HFunctor.Interpret:
icollect
,icollect1
now are more constrained: they only work on things that haveInterpret
instances for allMonoid m
orSemigroup m
inAltConst 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 ofDList
) and prevents one from making an oddInterpret
instance that does something weird with theDList
. This also allows us to drop the direct dlist >= 1.0 dependency. - Data.HFunctor.Interpret:
biapply
,bifanout
,bifanout1
added as contravariant consumer versions ofiget
,icollect
, andicollect1
. - Data.HBifunctor.Associative:
bicollect
bicollect1
removed because they really don’t make sense for associative tensors, which can only have at most one of each tensor. - Data.HBifunctor.Associative:
biapply
added as the contravariant consumer version ofbiget
. - Data.Functor.Invariant.Day: Add conversion functions from chains to the
covariant/invariant versions,
chainAp
,chainAp1
,chainDiv
, andchainDiv1
. - Data.Functor.Invariant.Night: Add conversion functions from chains to the
covariant/invariant versions,
chainDec
,chainDec1
,chainListF
,chainNonEmptyF
. Also add “undescored” versions to the covariant versions,toCoNight_
,chainListF_
,chainNonEmptyF_
, to more accurately represent the actual contravariant either-based day convolution. Also changedShare
toSwerve
. - Data.Functor.Combinator:
AltConst
re-exported.
Version 0.3.1.0
August 7, 2020
https://github.com/mstksg/functor-combinators/releases/tag/v0.3.1.0
- Data.HFunctor.Interpret:
getI
andcollectI
made more efficient, and renamed toiget
andicollect
, respectively, to mirrorbiget
andbicollect
.getI
andcollectI
are left in with a deprecation warning.icollect1
added to ensure a non-empty collection.AltConst
added to aid in implementation. - Data.HBifunctor.Associative:
bicollect1
added to ensure a non-empty collection. biget and bicollect made more efficient. - Data.Functor.Contravariant.Night, Data.Functor.Invariant.Night:
refuted
added for a convenientNot
. MissingInvariant
instance forNot
also added. - Data.HFunctor.Chain:
chainPair
andchain1Pair
renamed totoChain
andtoChain1
, respectively, to mirrortoListBy
andtoNonEmptyBy
.
Version 0.3.0.0
August 5, 2020
https://github.com/mstksg/functor-combinators/releases/tag/v0.3.0.0
-
Data.HBifunctor.Associative, Data.HBifunctor.Tensor: Support for
Contravariant
andInvariant
functor combinators. Main change to the infrastructure: add aFunctorBy
associated constraint toAssociative
to signal what “sort of functor” the tensor supports: it should either beUnconstrained
,Functor
,Contravariant
, orInvariant
. -
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:
- Data.Functor.Contravariant.Night:
Night
, a contravariant day convolution usingEither
, which is the tensor that generatesConclude
(andDecidable
kinda). - Data.Functor.Invariant.Day:
Day
, an invariant day convolution using tuples. - Data.Functor.Invariant.Night:
Night
, an invariant day convolution using either.
For the invariant day convolutions, we could write free monoids on them (like
Ap
/Div
/Dec
). But instead we just outsource our free structures toChain
, providing useful pattern synonyms and folding functions to pretend like we had an actual free structure. - Data.Functor.Contravariant.Night:
-
Data.Functor.Combinator: Useful functions in for working with divisible and decidable contravariant functors:
divideN
,diviseN
,concludeN
,decideN
,divideNRec
, anddiviseNRec
. -
Contravariant
andInvariant
instances for many types. -
Data.HFunctor.Final:
FreeOf
adjusted to allow for contravariant free types. -
Data.Functor.Combinator.Unsafe: Add
unsafeDivise
andunsafeConclude
, to mirror the situation withunsafeApply
andunsafePlus
.
Version 0.2.0.0
November 11, 2019
https://github.com/mstksg/functor-combinators/releases/tag/v0.2.0.0
-
Major restructuring of the hbifunctor-based classes.
Data.HBifunctor.Associative
andData.HBifunctor.Tensor
are 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 (
biget
, etc.)For the most part, the migration would involve:
SF
,MF
are nowNonEmptyBy
andListBy
, respectively.-SF
and-MF
as suffixes for function names now become-NE
and-LB
.
-
upgradeC
no longer exists; use unsafe functions from Data.Functor.Combinator.Unsafe instead, on a per-tensor basis. -
Restructuring of
Interpret
: It now takes an extra type parameter, the type to interpret into. This makes it more consistent with the newMonoidIn
andSemigroupIn
. 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 ofinstance Interpret MyType where type C MyType = Monad
you would write:
instance Monad f => Interpret MyType f where
Version 0.1.1.1
July 13, 2019
https://github.com/mstksg/functor-combinators/releases/tag/v0.1.1.1
- Moved to trivial-constraints-0.6.0.0
Version 0.1.1.0
June 19, 2019
https://github.com/mstksg/functor-combinators/releases/tag/v0.1.1.0
appendChain
andappendChain1
Version 0.1.0.1
June 19, 2019
https://github.com/mstksg/functor-combinators/releases/tag/v0.1.0.1
- Small tweaks for haddock generation and dependency bounds.
Version 0.1.0.0
June 19, 2019
https://github.com/mstksg/functor-combinators/releases/tag/v0.1.0.0
- Initial release