-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Tools for functor combinator-based program design -- -- 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. In the process, you can design -- featureful programs by composing smaller "primitives" using basic -- unversal combinators. -- -- The main entry point is 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. -- -- This library does not define new functor combinators for the most -- part, but rather re-exports them from different parts of the Haskell -- ecosystem and provides a uniform interface. -- -- See the README for a quick overview, and also -- https://blog.jle.im/entry/functor-combinatorpedia.html for an -- in-depth dive into the motivation behind functor combinator-driven -- development, examples of the functor combinators in this library, and -- details about how to use these abstractions! @package functor-combinators @version 0.3.0.0 -- | The church-encoded Freer Monad. Basically provides the free -- monad in a way that is compatible with HFunctor and -- Interpret. We also have the "semigroup" version Free1, -- which is the free Bind. -- -- The module also provides a version of :.: (or Compose), -- Comp, in a way that is compatible with HBifunctor and -- the related typeclasses. module Control.Monad.Freer.Church -- | A Free f is f enhanced with "sequential -- binding" capabilities. It allows you to sequence multiple fs -- one after the other, and also to determine "what f to -- sequence" based on the result of the computation so far. -- -- Essentially, you can think of this as "giving f a -- Monad instance", with all that that entails (return, -- >>=, etc.). -- -- Lift f into it with inject :: f a -> Free f -- a. When you finally want to "use" it, you can interpret it into -- any monadic context: -- --
-- interpret -- :: Monad g -- => (forall x. f x -> g x) -- -> Free f a -- -> g a ---- -- Structurally, this is equivalent to many "nested" f's. A value of type -- Free f a is either: -- --
a
f a
f (f a)
f (f (f a))
-- viewF :: (f <~> g) -> f a -> g a -- reviewF :: (f <~> g) -> g a -> a a ---- -- Use viewF to extract the "f to g" function, -- and reviewF to extract the "g to f" function. -- Reviewing and viewing the same value (or vice versa) leaves the value -- unchanged. -- -- One nice thing is that we can compose isomorphisms using . from -- Prelude: -- --
-- (.) :: f <~> g -- -> g <~> h -- -> f <~> h ---- -- Another nice thing about this representation is that we have the -- "identity" isomorphism by using id from Prelude. -- --
-- id :: f <~> g ---- -- As a convention, most isomorphisms have form "X-ing", where the -- forwards function is "ing". For example, we have: -- --
-- splittingSF :: Monoidal t => SF t a <~> t f (MF t f) -- splitSF :: Monoidal t => SF t a ~> t f (MF t f) --type f <~> g = forall p a. Profunctor p => p (g a) (g a) -> p (f a) (f a) infixr 0 <~> -- | Create an f <~> g by providing both legs of the -- isomorphism (the f a -> g a and the g a -> f -- a. isoF :: (f ~> g) -> (g ~> f) -> f <~> g -- | Use a <~> by retrieving the "forward" function: -- --
-- viewF :: (f ~ g) -> f a -> g a --viewF :: (f <~> g) -> f ~> g -- | Use a <~> by retrieving the "backwards" function: -- --
-- viewF :: (f ~ g) -> f a -> g a --reviewF :: (f <~> g) -> g ~> f -- | Lift a function g a ~> g a to be a function f a -> -- f a, given an isomorphism between the two. -- -- One neat thing is that overF i id == id. overF :: (f <~> g) -> (g ~> g) -> f ~> f -- | Reverse an isomorphism. -- --
-- viewF (fromF i) == reviewF i -- reviewF (fromF i) == viewF i --fromF :: forall (f :: Type -> Type) (g :: Type -> Type). () => (f <~> g) -> g <~> f -- | The contravariant counterpart of Apply: like Divisible, -- but without conquer. This is only a part of this library -- currently for compatibility, until it is (hopefully) merged into -- semigroupoids. module Data.Functor.Contravariant.Divise -- | The contravariant analogue of Apply; it is Divisible -- without conquer. -- -- If one thinks of f a as a consumer of as, then -- divise allows one to handle the consumption of a value by -- splitting it between two consumers that consume separate parts of -- a. -- -- divise takes the "splitting" method and the two sub-consumers, -- and returns the wrapped/combined consumer. -- -- All instances of Divisible should be instances of Divise -- with divise = divide. -- -- The guarantee that a function polymorphic over of Divise -- f provides that Divisible f doesn't that any -- input consumed will be passed to at least one sub-consumer; it won't -- potentially disappear into the void, as is possible if conquer -- is available. -- -- Mathematically, a functor being an instance of Divise means -- that it is "semgroupoidal" with respect to the contravariant (tupling) -- Day convolution. That is, it is possible to define a function (f -- Day f) a -> f a in a way that is associative. class Contravariant f => Divise f -- | Takes a "splitting" method and the two sub-consumers, and returns the -- wrapped/combined consumer. divise :: Divise f => (a -> (b, c)) -> f b -> f c -> f a -- | Combine a consumer of a with a consumer of b to get -- a consumer of (a, b). -- --
-- divised = divise id --divised :: Divise f => f a -> f b -> f (a, b) -- | Wrap a Divisible to be used as a member of Divise newtype WrappedDivisible f a WrapDivisible :: f a -> WrappedDivisible f a [unwrapDivisible] :: WrappedDivisible f a -> f a instance Data.Functor.Contravariant.Contravariant f => Data.Functor.Contravariant.Contravariant (Data.Functor.Contravariant.Divise.WrappedDivisible f) instance Data.Functor.Contravariant.Divisible.Divisible f => Data.Functor.Contravariant.Divise.Divise (Data.Functor.Contravariant.Divise.WrappedDivisible f) instance GHC.Base.Semigroup r => Data.Functor.Contravariant.Divise.Divise (Data.Functor.Contravariant.Op r) instance GHC.Base.Semigroup m => Data.Functor.Contravariant.Divise.Divise (Data.Functor.Const.Const m) instance GHC.Base.Semigroup m => Data.Functor.Contravariant.Divise.Divise (Data.Functor.Constant.Constant m) instance Data.Functor.Contravariant.Divise.Divise Data.Functor.Contravariant.Comparison instance Data.Functor.Contravariant.Divise.Divise Data.Functor.Contravariant.Equivalence instance Data.Functor.Contravariant.Divise.Divise Data.Functor.Contravariant.Predicate instance Data.Functor.Contravariant.Divise.Divise Data.Proxy.Proxy instance Data.Functor.Contravariant.Divise.Divise f => Data.Functor.Contravariant.Divise.Divise (Data.Semigroup.Internal.Alt f) instance Data.Functor.Contravariant.Divise.Divise GHC.Generics.U1 instance Data.Functor.Contravariant.Divise.Divise GHC.Generics.V1 instance Data.Functor.Contravariant.Divise.Divise f => Data.Functor.Contravariant.Divise.Divise (GHC.Generics.Rec1 f) instance Data.Functor.Contravariant.Divise.Divise f => Data.Functor.Contravariant.Divise.Divise (GHC.Generics.M1 i c f) instance (Data.Functor.Contravariant.Divise.Divise f, Data.Functor.Contravariant.Divise.Divise g) => Data.Functor.Contravariant.Divise.Divise (f GHC.Generics.:*: g) instance (Data.Functor.Bind.Class.Apply f, Data.Functor.Contravariant.Divise.Divise g) => Data.Functor.Contravariant.Divise.Divise (f GHC.Generics.:.: g) instance Data.Functor.Contravariant.Divise.Divise f => Data.Functor.Contravariant.Divise.Divise (Control.Applicative.Backwards.Backwards f) instance Data.Functor.Contravariant.Divise.Divise m => Data.Functor.Contravariant.Divise.Divise (Control.Monad.Trans.Error.ErrorT e m) instance Data.Functor.Contravariant.Divise.Divise m => Data.Functor.Contravariant.Divise.Divise (Control.Monad.Trans.Except.ExceptT e m) instance Data.Functor.Contravariant.Divise.Divise f => Data.Functor.Contravariant.Divise.Divise (Control.Monad.Trans.Identity.IdentityT f) instance Data.Functor.Contravariant.Divise.Divise m => Data.Functor.Contravariant.Divise.Divise (Control.Monad.Trans.List.ListT m) instance Data.Functor.Contravariant.Divise.Divise m => Data.Functor.Contravariant.Divise.Divise (Control.Monad.Trans.Maybe.MaybeT m) instance Data.Functor.Contravariant.Divise.Divise m => Data.Functor.Contravariant.Divise.Divise (Control.Monad.Trans.Reader.ReaderT r m) instance Data.Functor.Contravariant.Divise.Divise m => Data.Functor.Contravariant.Divise.Divise (Control.Monad.Trans.RWS.Lazy.RWST r w s m) instance Data.Functor.Contravariant.Divise.Divise m => Data.Functor.Contravariant.Divise.Divise (Control.Monad.Trans.RWS.Strict.RWST r w s m) instance Data.Functor.Contravariant.Divise.Divise m => Data.Functor.Contravariant.Divise.Divise (Control.Monad.Trans.State.Lazy.StateT s m) instance Data.Functor.Contravariant.Divise.Divise m => Data.Functor.Contravariant.Divise.Divise (Control.Monad.Trans.State.Strict.StateT s m) instance Data.Functor.Contravariant.Divise.Divise m => Data.Functor.Contravariant.Divise.Divise (Control.Monad.Trans.Writer.Lazy.WriterT w m) instance Data.Functor.Contravariant.Divise.Divise m => Data.Functor.Contravariant.Divise.Divise (Control.Monad.Trans.Writer.Strict.WriterT w m) instance (Data.Functor.Bind.Class.Apply f, Data.Functor.Contravariant.Divise.Divise g) => Data.Functor.Contravariant.Divise.Divise (Data.Functor.Compose.Compose f g) instance (Data.Functor.Contravariant.Divise.Divise f, Data.Functor.Contravariant.Divise.Divise g) => Data.Functor.Contravariant.Divise.Divise (Data.Functor.Product.Product f g) instance Data.Functor.Contravariant.Divise.Divise f => Data.Functor.Contravariant.Divise.Divise (Data.Functor.Reverse.Reverse f) -- | The contravariant counterpart of Alt: like Decidable, -- but without loss or a superclass constraint on -- Divisible. This is only a part of this library currently for -- compatibility, until it is (hopefully) merged into -- semigroupoids. module Data.Functor.Contravariant.Decide -- | The contravariant analogue of Alt. -- -- If one thinks of f a as a consumer of as, then -- decide allows one to handle the consumption of a value by -- choosing to handle it via exactly one of two independent consumers. It -- redirects the input completely into one of two consumers. -- -- decide takes the "decision" method and the two potential -- consumers, and returns the wrapped/combined consumer. -- -- Mathematically, a functor being an instance of Decide means -- that it is "semgroupoidal" with respect to the contravariant -- "either-based" Day convolution (data EitherDay f g a = forall b c. -- EitherDay (f b) (g c) (a -> Either b c)). That is, it is -- possible to define a function (f EitherDay f) a -> f -- a in a way that is associative. class Contravariant f => Decide f -- | Takes the "decision" method and the two potential consumers, and -- returns the wrapped/combined consumer. decide :: Decide f => (a -> Either b c) -> f b -> f c -> f a -- | For decided x y, the resulting f (Either b -- c) will direct Lefts to be consumed by x, and -- Rights to be consumed by y. decided :: Decide f => f b -> f c -> f (Either b c) instance Data.Functor.Contravariant.Divisible.Decidable f => Data.Functor.Contravariant.Decide.Decide (Data.Functor.Contravariant.Divise.WrappedDivisible f) instance Data.Functor.Contravariant.Decide.Decide Data.Functor.Contravariant.Comparison instance Data.Functor.Contravariant.Decide.Decide Data.Functor.Contravariant.Equivalence instance Data.Functor.Contravariant.Decide.Decide Data.Functor.Contravariant.Predicate instance Data.Functor.Contravariant.Decide.Decide (Data.Functor.Contravariant.Op r) instance Data.Functor.Contravariant.Decide.Decide f => Data.Functor.Contravariant.Decide.Decide (Data.Semigroup.Internal.Alt f) instance Data.Functor.Contravariant.Decide.Decide GHC.Generics.U1 instance Data.Functor.Contravariant.Decide.Decide GHC.Generics.V1 instance Data.Functor.Contravariant.Decide.Decide f => Data.Functor.Contravariant.Decide.Decide (GHC.Generics.Rec1 f) instance Data.Functor.Contravariant.Decide.Decide f => Data.Functor.Contravariant.Decide.Decide (GHC.Generics.M1 i c f) instance (Data.Functor.Contravariant.Decide.Decide f, Data.Functor.Contravariant.Decide.Decide g) => Data.Functor.Contravariant.Decide.Decide (f GHC.Generics.:*: g) instance (Data.Functor.Bind.Class.Apply f, Data.Functor.Contravariant.Decide.Decide g) => Data.Functor.Contravariant.Decide.Decide (f GHC.Generics.:.: g) instance Data.Functor.Contravariant.Decide.Decide f => Data.Functor.Contravariant.Decide.Decide (Control.Applicative.Backwards.Backwards f) instance Data.Functor.Contravariant.Decide.Decide f => Data.Functor.Contravariant.Decide.Decide (Control.Monad.Trans.Identity.IdentityT f) instance Data.Functor.Contravariant.Decide.Decide m => Data.Functor.Contravariant.Decide.Decide (Control.Monad.Trans.Reader.ReaderT r m) instance Data.Functor.Contravariant.Decide.Decide m => Data.Functor.Contravariant.Decide.Decide (Control.Monad.Trans.RWS.Lazy.RWST r w s m) instance Data.Functor.Contravariant.Decide.Decide m => Data.Functor.Contravariant.Decide.Decide (Control.Monad.Trans.RWS.Strict.RWST r w s m) instance Data.Functor.Contravariant.Divise.Divise m => Data.Functor.Contravariant.Decide.Decide (Control.Monad.Trans.List.ListT m) instance Data.Functor.Contravariant.Divise.Divise m => Data.Functor.Contravariant.Decide.Decide (Control.Monad.Trans.Maybe.MaybeT m) instance Data.Functor.Contravariant.Decide.Decide m => Data.Functor.Contravariant.Decide.Decide (Control.Monad.Trans.State.Lazy.StateT s m) instance Data.Functor.Contravariant.Decide.Decide m => Data.Functor.Contravariant.Decide.Decide (Control.Monad.Trans.State.Strict.StateT s m) instance Data.Functor.Contravariant.Decide.Decide m => Data.Functor.Contravariant.Decide.Decide (Control.Monad.Trans.Writer.Lazy.WriterT w m) instance Data.Functor.Contravariant.Decide.Decide m => Data.Functor.Contravariant.Decide.Decide (Control.Monad.Trans.Writer.Strict.WriterT w m) instance (Data.Functor.Bind.Class.Apply f, Data.Functor.Contravariant.Decide.Decide g) => Data.Functor.Contravariant.Decide.Decide (Data.Functor.Compose.Compose f g) instance (Data.Functor.Contravariant.Decide.Decide f, Data.Functor.Contravariant.Decide.Decide g) => Data.Functor.Contravariant.Decide.Decide (Data.Functor.Product.Product f g) instance Data.Functor.Contravariant.Decide.Decide f => Data.Functor.Contravariant.Decide.Decide (Data.Functor.Reverse.Reverse f) instance Data.Functor.Contravariant.Decide.Decide Data.Proxy.Proxy -- | The contravariant counterpart of Plus: like Decidable, -- but without needing a Divisible constraint. This is only a part -- of this library currently for compatibility, until it is (hopefully) -- merged into semigroupoids. module Data.Functor.Contravariant.Conclude -- | The contravariant analogue of Plus. Adds on to Decide -- the ability to express a combinator that rejects all input, to act as -- the dead-end. Essentially Decidable without a superclass -- constraint on Divisible. -- -- If one thinks of f a as a consumer of as, then -- conclude defines a consumer that cannot ever receive any -- input. -- -- Conclude acts as an identity with decide, because any decision -- that involves conclude must necessarily always pick the -- other option. -- -- That is, for, say, -- --
-- decide f x concluded ---- -- f is the deciding function that picks which of the inputs of -- decide to direct input to; in the situation above, f -- must always direct all input to x, and never -- concluded. -- -- Mathematically, a functor being an instance of Decide means -- that it is "monoidal" with respect to the contravariant "either-based" -- Day convolution described in the documentation of Decide. On -- top of Decide, it adds a way to construct an "identity" -- conclude where decide f x (conclude q) == x, and -- decide g (conclude r) y == y. class Decide f => Conclude f -- | The consumer that cannot ever receive any input. conclude :: Conclude f => (a -> Void) -> f a -- | A potentially more meaningful form of conclude, the consumer -- that cannot ever receive any input. That is because it expects -- only input of type Void, but such a type has no values. -- --
-- concluded = conclude id --concluded :: Conclude f => f Void instance Data.Functor.Contravariant.Divisible.Decidable f => Data.Functor.Contravariant.Conclude.Conclude (Data.Functor.Contravariant.Divise.WrappedDivisible f) instance Data.Functor.Contravariant.Conclude.Conclude Data.Functor.Contravariant.Comparison instance Data.Functor.Contravariant.Conclude.Conclude Data.Functor.Contravariant.Equivalence instance Data.Functor.Contravariant.Conclude.Conclude Data.Functor.Contravariant.Predicate instance Data.Functor.Contravariant.Conclude.Conclude (Data.Functor.Contravariant.Op r) instance Data.Functor.Contravariant.Conclude.Conclude Data.Proxy.Proxy instance Data.Functor.Contravariant.Conclude.Conclude f => Data.Functor.Contravariant.Conclude.Conclude (Data.Semigroup.Internal.Alt f) instance Data.Functor.Contravariant.Conclude.Conclude GHC.Generics.U1 instance Data.Functor.Contravariant.Conclude.Conclude f => Data.Functor.Contravariant.Conclude.Conclude (GHC.Generics.Rec1 f) instance Data.Functor.Contravariant.Conclude.Conclude f => Data.Functor.Contravariant.Conclude.Conclude (GHC.Generics.M1 i c f) instance (Data.Functor.Contravariant.Conclude.Conclude f, Data.Functor.Contravariant.Conclude.Conclude g) => Data.Functor.Contravariant.Conclude.Conclude (f GHC.Generics.:*: g) instance (Data.Functor.Bind.Class.Apply f, GHC.Base.Applicative f, Data.Functor.Contravariant.Conclude.Conclude g) => Data.Functor.Contravariant.Conclude.Conclude (f GHC.Generics.:.: g) instance Data.Functor.Contravariant.Conclude.Conclude f => Data.Functor.Contravariant.Conclude.Conclude (Control.Applicative.Backwards.Backwards f) instance Data.Functor.Contravariant.Conclude.Conclude f => Data.Functor.Contravariant.Conclude.Conclude (Control.Monad.Trans.Identity.IdentityT f) instance Data.Functor.Contravariant.Conclude.Conclude m => Data.Functor.Contravariant.Conclude.Conclude (Control.Monad.Trans.Reader.ReaderT r m) instance Data.Functor.Contravariant.Conclude.Conclude m => Data.Functor.Contravariant.Conclude.Conclude (Control.Monad.Trans.RWS.Lazy.RWST r w s m) instance Data.Functor.Contravariant.Conclude.Conclude m => Data.Functor.Contravariant.Conclude.Conclude (Control.Monad.Trans.RWS.Strict.RWST r w s m) instance (Data.Functor.Contravariant.Divisible.Divisible m, Data.Functor.Contravariant.Divise.Divise m) => Data.Functor.Contravariant.Conclude.Conclude (Control.Monad.Trans.List.ListT m) instance (Data.Functor.Contravariant.Divisible.Divisible m, Data.Functor.Contravariant.Divise.Divise m) => Data.Functor.Contravariant.Conclude.Conclude (Control.Monad.Trans.Maybe.MaybeT m) instance Data.Functor.Contravariant.Conclude.Conclude m => Data.Functor.Contravariant.Conclude.Conclude (Control.Monad.Trans.State.Lazy.StateT s m) instance Data.Functor.Contravariant.Conclude.Conclude m => Data.Functor.Contravariant.Conclude.Conclude (Control.Monad.Trans.State.Strict.StateT s m) instance Data.Functor.Contravariant.Conclude.Conclude m => Data.Functor.Contravariant.Conclude.Conclude (Control.Monad.Trans.Writer.Lazy.WriterT w m) instance Data.Functor.Contravariant.Conclude.Conclude m => Data.Functor.Contravariant.Conclude.Conclude (Control.Monad.Trans.Writer.Strict.WriterT w m) instance (Data.Functor.Bind.Class.Apply f, GHC.Base.Applicative f, Data.Functor.Contravariant.Conclude.Conclude g) => Data.Functor.Contravariant.Conclude.Conclude (Data.Functor.Compose.Compose f g) instance (Data.Functor.Contravariant.Conclude.Conclude f, Data.Functor.Contravariant.Conclude.Conclude g) => Data.Functor.Contravariant.Conclude.Conclude (Data.Functor.Product.Product f g) instance Data.Functor.Contravariant.Conclude.Conclude f => Data.Functor.Contravariant.Conclude.Conclude (Data.Functor.Reverse.Reverse f) -- | Working with non-standard typeclasses like Plus, Apply, -- Bind, and Pointed will sometimes cause problems when -- using with libraries that do not provide instances, even though their -- types already are instances of Alternative or -- Applicative or Monad. -- -- This module provides unsafe methods to "promote" Applicative -- instances to Apply, Alternative to Plus, etc. -- -- They are unsafe in the sense that if those types already have -- those instances, this will cause overlapping instances errors or -- problems with coherence. Because of this, you should always use these -- with specific fs, and never in a polymorphic way over -- f. module Data.Functor.Combinator.Unsafe -- | For any Alternative f, produce a value that would -- require Plus f. -- -- Always use with concrete and specific f only, and never use -- with any f that already has a Plus instance. -- -- See documentation for upgradeC for example usages. -- -- The Proxy argument allows you to specify which specific -- f you want to enhance. You can pass in something like -- Proxy @MyFunctor. unsafePlus :: forall f proxy r. Alternative f => proxy f -> (Plus f => r) -> r -- | For any Applicative f, produce a value that would -- require Apply f. -- -- Always use with concrete and specific f only, and never use -- with any f that already has a Apply instance. -- -- See documentation for upgradeC for example usages. -- -- The Proxy argument allows you to specify which specific -- f you want to enhance. You can pass in something like -- Proxy @MyFunctor. unsafeApply :: forall f proxy r. Applicative f => proxy f -> (Apply f => r) -> r -- | For any Monad f, produce a value that would require -- Bind f. -- -- Always use with concrete and specific f only, and never use -- with any f that already has a Bind instance. -- -- See documentation for upgradeC for example usages. -- -- The Proxy argument allows you to specify which specific -- f you want to enhance. You can pass in something like -- Proxy @MyFunctor. unsafeBind :: forall f proxy r. Monad f => proxy f -> (Bind f => r) -> r -- | For any Applicative f, produce a value that would -- require Pointed f. -- -- Always use with concrete and specific f only, and never use -- with any f that already has a Pointed instance. -- -- See documentation for upgradeC for example usages. -- -- The Proxy argument allows you to specify which specific -- f you want to enhance. You can pass in something like -- Proxy @MyFunctor. unsafePointed :: forall f proxy r. Applicative f => proxy f -> (Pointed f => r) -> r -- | For any Decidable f, produce a value that would -- require Conclude f. -- -- Always use with concrete and specific f only, and never use -- with any f that already has a Conclude instance. -- -- See documentation for upgradeC for example usages. -- -- The Proxy argument allows you to specify which specific -- f you want to enhance. You can pass in something like -- Proxy @MyFunctor. unsafeConclude :: forall f proxy r. Decidable f => proxy f -> (Conclude f => r) -> r -- | For any Divisible f, produce a value that would -- require Divise f. -- -- Always use with concrete and specific f only, and never use -- with any f that already has a Divise instance. -- -- See documentation for upgradeC for example usages. -- -- The Proxy argument allows you to specify which specific -- f you want to enhance. You can pass in something like -- Proxy @MyFunctor. unsafeDivise :: forall f proxy r. Divisible f => proxy f -> (Divise f => r) -> r instance GHC.Base.Applicative f => Data.Pointed.Pointed (Data.Functor.Combinator.Unsafe.PointMe f) -- | This module provides functor combinators that are the fixed points of -- applications of :+: and These1. They are useful for -- their Interpret instances, along with their relationship to the -- Monoidal instances of :+: and These1. module Control.Applicative.Step -- | An f a, along with a Natural index. -- --
-- Step f a ~ (Natural, f a) -- Step f ~ ((,) Natural) :.: f -- functor composition ---- -- It is the fixed point of infinite applications of :+: (functor -- sums). -- -- Intuitively, in an infinite f :+: f :+: f :+: f ..., you have -- exactly one f somewhere. A Step f a -- has that f, with a Natural giving you "where" the -- f is in the long chain. -- -- Can be useful for using with the Monoidal instance of -- :+:. -- -- interpreting it requires no constraint on the target context. -- -- Note that this type and its instances equivalent to EnvT -- (Sum Natural). data Step f a Step :: Natural -> f a -> Step f a [stepPos] :: Step f a -> Natural [stepVal] :: Step f a -> f a -- | A non-empty map of Natural to f a. Basically, contains -- multiple f as, each at a given Natural index. -- --
-- Steps f a ~ Map Natural (f a) -- Steps f ~ Map Natural :.: f -- functor composition ---- -- It is the fixed point of applications of TheseT. -- -- You can think of this as an infinite sparse array of f as. -- -- Intuitively, in an infinite f `TheseT` f `TheseT` f `TheseT` f -- ..., each of those infinite positions may have an f in -- them. However, because of the at-least-one nature of TheseT, we -- know we have at least one f at one position somewhere. -- -- A Steps f a has potentially many fs, each -- stored at a different Natural position, with the guaruntee that -- at least one f exists. -- -- Can be useful for using with the Monoidal instance of -- TheseT. -- -- interpreting it requires at least an Alt instance in the -- target context, since we have to handle potentially more than one -- f. -- -- This type is essentailly the same as NEMapF (Sum -- Natural) (except with a different Semigroup -- instance). newtype Steps f a Steps :: NEMap Natural (f a) -> Steps f a [getSteps] :: Steps f a -> NEMap Natural (f a) -- | An f a, along with a Bool flag -- --
-- Flagged f a ~ (Bool, f a) -- Flagged f ~ ((,) Bool) :.: f -- functor composition ---- -- Creation with inject or pure uses False as the -- boolean. -- -- You can think of it as an f a that is "flagged" with a -- boolean value, and that value can indicuate whether or not it is -- "pure" (made with inject or pure) as False, or -- "impure" (made from some other source) as True. However, -- False may be always created directly, of course, using the -- constructor. -- -- You can think of it like a Step that is either 0 or 1, as well. -- -- interpreting it requires no constraint on the target context. -- -- This type is equivalent (along with its instances) to: -- -- data Flagged f a Flagged :: Bool -> f a -> Flagged f a [flaggedFlag] :: Flagged f a -> Bool [flaggedVal] :: Flagged f a -> f a -- | Unshift an item into a Step. Because a Step f -- is f :+: f :+: f :+: f :+: ... forever, this basically conses -- an additional possibility of f to the beginning of it all. -- -- You can think of it as reassociating -- --
-- f :+: ( f :+: f :+: f :+: ...) ---- -- into -- --
-- f :+: f :+: f :+: f :+: ... ---- --
-- stepUp (L1 "hello") -- -- Step 0 "hello" -- stepUp (R1 (Step 1 "hello")) -- -- Step 2 "hello" ---- -- Forms an isomorphism with stepDown (see stepping). stepUp :: (f :+: Step f) ~> Step f -- | Pop off the first item in a Step. Because a Step -- f is f :+: f :+: f :+: ... forever, this matches on the -- first branch. -- -- You can think of it as reassociating -- --
-- f :+: f :+: f :+: f :+: ... ---- -- into -- --
-- f :+: ( f :+: f :+: f :+: ...) ---- --
-- stepDown (Step 2 "hello") -- -- R1 (Step 1 "hello") -- stepDown (Step 0 "hello") -- -- L1 "hello" ---- -- Forms an isomorphism with stepUp (see stepping). stepDown :: Step f ~> (f :+: Step f) -- | "Uncons and cons" an f branch before a Step. This is -- basically a witness that stepDown and stepUp form an -- isomorphism. stepping :: Step f <~> (f :+: Step f) -- | Unshift an item into a Steps. Because a Steps f -- is f These1 f These1 f These1 f These1 -- ... forever, this basically conses an additional possibility of -- f to the beginning of it all. -- -- You can think of it as reassociating -- --
-- f These1 ( f These1 f These1 f These1 ...) ---- -- into -- --
-- f These1 f These1 f These1 f These1 ... ---- -- If you give: -- --
-- f These1 f These1 f These1 f These1 ... ---- -- into -- --
-- f These1 ( f These1 f These1 f These1 ...) ---- -- It returns: -- --
-- NonEmptyF f -- ~ f -- one f -- :+: (f :*: f) -- two f's -- :+: (f :*: f :*: f) -- three f's -- :+: (f :*: f :*: f :*: f) -- four f's -- :+: ... -- etc. ---- -- This is the Free Plus on any Functor f. -- -- Incidentally, if used with a Contravariant f, this is -- instead the free Divise. newtype NonEmptyF f a NonEmptyF :: NonEmpty (f a) -> NonEmptyF f a [runNonEmptyF] :: NonEmptyF f a -> NonEmpty (f a) -- | Treat a NonEmptyF f as a product between an f -- and a ListF f. -- -- nonEmptyProd is the record accessor. pattern ProdNonEmpty :: (f :*: ListF f) a -> NonEmptyF f a -- | Map a function over the inside of a NonEmptyF. mapNonEmptyF :: (NonEmpty (f a) -> NonEmpty (g b)) -> NonEmptyF f a -> NonEmptyF g b -- | Convert a NonEmptyF into a ListF with at least one item. toListF :: NonEmptyF f ~> ListF f -- | Convert a ListF either a NonEmptyF, or a Proxy in -- the case that the list was empty. fromListF :: ListF f ~> (Proxy :+: NonEmptyF f) -- | A maybe f a. -- -- Can be useful for describing a "an f a that may or may not be -- there". -- -- This is the free structure for a "fail"-like typeclass that would only -- have zero :: f a. newtype MaybeF f a MaybeF :: Maybe (f a) -> MaybeF f a [runMaybeF] :: MaybeF f a -> Maybe (f a) -- | Map a function over the inside of a MaybeF. mapMaybeF :: (Maybe (f a) -> Maybe (g b)) -> MaybeF f a -> MaybeF g b -- | Convert a ListF into a MaybeF containing the first f -- a in the list, if it exists. listToMaybeF :: ListF f ~> MaybeF f -- | Convert a MaybeF into a ListF with zero or one items. maybeToListF :: MaybeF f ~> ListF f -- | A map of f as, indexed by keys of type k. It can be -- useful for represeting a product of many different values of type -- f a, each "at" a different k location. -- -- Can be considered a combination of EnvT and ListF, in a -- way --- a MapF k f a is like a ListF -- (EnvT k f) a with unique (and ordered) keys. -- -- One use case might be to extend a schema with many "options", indexed -- by some string. -- -- For example, if you had a command line argument parser for a single -- command -- --
-- data Command a ---- -- Then you can represent a command line argument parser for -- multiple named commands with -- --
-- type Commands = MapF String Command ---- -- See NEMapF for a non-empty variant, if you want to enforce that -- your bag has at least one f a. newtype MapF k f a MapF :: Map k (f a) -> MapF k f a [runMapF] :: MapF k f a -> Map k (f a) -- | A non-empty map of f as, indexed by keys of type k. -- It can be useful for represeting a product of many different values of -- type f a, each "at" a different k location, where -- you need to have at least one f a at all times. -- -- Can be considered a combination of EnvT and NonEmptyF, -- in a way --- an NEMapF k f a is like a -- NonEmptyF (EnvT k f) a with unique (and -- ordered) keys. -- -- See MapF for some use cases. newtype NEMapF k f a NEMapF :: NEMap k (f a) -> NEMapF k f a [runNEMapF] :: NEMapF k f a -> NEMap k (f a) instance (GHC.Classes.Ord k, Data.Functor.Classes.Ord1 f) => Data.Functor.Classes.Ord1 (Control.Applicative.ListF.NEMapF k f) instance (GHC.Classes.Ord k, GHC.Read.Read k, Data.Functor.Classes.Read1 f) => Data.Functor.Classes.Read1 (Control.Applicative.ListF.NEMapF k f) instance Data.Semigroup.Foldable.Class.Foldable1 f => Data.Semigroup.Foldable.Class.Foldable1 (Control.Applicative.ListF.NEMapF k f) instance Data.Semigroup.Traversable.Class.Traversable1 f => Data.Semigroup.Traversable.Class.Traversable1 (Control.Applicative.ListF.NEMapF k f) instance (GHC.Classes.Ord k, Data.Functor.Alt.Alt f) => GHC.Base.Semigroup (Control.Applicative.ListF.NEMapF k f a) instance (GHC.Base.Functor f, GHC.Classes.Ord k) => Data.Functor.Alt.Alt (Control.Applicative.ListF.NEMapF k f) instance (GHC.Base.Monoid k, Data.Pointed.Pointed f) => Data.Pointed.Pointed (Control.Applicative.ListF.NEMapF k f) instance (GHC.Classes.Eq k, Data.Functor.Classes.Eq1 f) => Data.Functor.Classes.Eq1 (Control.Applicative.ListF.NEMapF k f) instance (GHC.Show.Show k, Data.Functor.Classes.Show1 f) => Data.Functor.Classes.Show1 (Control.Applicative.ListF.NEMapF k f) instance forall k1 k2 (f :: k2 -> *) (a :: k2). (Data.Typeable.Internal.Typeable a, Data.Typeable.Internal.Typeable f, Data.Typeable.Internal.Typeable k2, Data.Data.Data k1, Data.Data.Data (f a), GHC.Classes.Ord k1) => Data.Data.Data (Control.Applicative.ListF.NEMapF k1 f a) instance forall k1 k2 (f :: k2 -> *) (a :: k2). GHC.Generics.Generic (Control.Applicative.ListF.NEMapF k1 f a) instance Data.Traversable.Traversable f => Data.Traversable.Traversable (Control.Applicative.ListF.NEMapF k f) instance Data.Foldable.Foldable f => Data.Foldable.Foldable (Control.Applicative.ListF.NEMapF k f) instance GHC.Base.Functor f => GHC.Base.Functor (Control.Applicative.ListF.NEMapF k f) instance forall k1 k2 (f :: k2 -> *) (a :: k2). (GHC.Classes.Ord k1, GHC.Classes.Ord (f a)) => GHC.Classes.Ord (Control.Applicative.ListF.NEMapF k1 f a) instance forall k1 k2 (f :: k2 -> *) (a :: k2). (GHC.Classes.Eq k1, GHC.Classes.Eq (f a)) => GHC.Classes.Eq (Control.Applicative.ListF.NEMapF k1 f a) instance forall k1 k2 (f :: k2 -> *) (a :: k2). (GHC.Classes.Ord k1, GHC.Read.Read k1, GHC.Read.Read (f a)) => GHC.Read.Read (Control.Applicative.ListF.NEMapF k1 f a) instance forall k1 k2 (f :: k2 -> *) (a :: k2). (GHC.Show.Show k1, GHC.Show.Show (f a)) => GHC.Show.Show (Control.Applicative.ListF.NEMapF k1 f a) instance (GHC.Classes.Ord k, Data.Functor.Classes.Ord1 f) => Data.Functor.Classes.Ord1 (Control.Applicative.ListF.MapF k f) instance (GHC.Classes.Ord k, GHC.Read.Read k, Data.Functor.Classes.Read1 f) => Data.Functor.Classes.Read1 (Control.Applicative.ListF.MapF k f) instance (GHC.Classes.Ord k, Data.Functor.Alt.Alt f) => GHC.Base.Semigroup (Control.Applicative.ListF.MapF k f a) instance (GHC.Classes.Ord k, Data.Functor.Alt.Alt f) => GHC.Base.Monoid (Control.Applicative.ListF.MapF k f a) instance (GHC.Base.Functor f, GHC.Classes.Ord k) => Data.Functor.Alt.Alt (Control.Applicative.ListF.MapF k f) instance (GHC.Base.Functor f, GHC.Classes.Ord k) => Data.Functor.Plus.Plus (Control.Applicative.ListF.MapF k f) instance (GHC.Base.Monoid k, Data.Pointed.Pointed f) => Data.Pointed.Pointed (Control.Applicative.ListF.MapF k f) instance (GHC.Classes.Eq k, Data.Functor.Classes.Eq1 f) => Data.Functor.Classes.Eq1 (Control.Applicative.ListF.MapF k f) instance (GHC.Show.Show k, Data.Functor.Classes.Show1 f) => Data.Functor.Classes.Show1 (Control.Applicative.ListF.MapF k f) instance forall k1 k2 (f :: k2 -> *) (a :: k2). (Data.Typeable.Internal.Typeable a, Data.Typeable.Internal.Typeable f, Data.Typeable.Internal.Typeable k2, Data.Data.Data k1, Data.Data.Data (f a), GHC.Classes.Ord k1) => Data.Data.Data (Control.Applicative.ListF.MapF k1 f a) instance forall k1 k2 (f :: k2 -> *) (a :: k2). GHC.Generics.Generic (Control.Applicative.ListF.MapF k1 f a) instance Data.Traversable.Traversable f => Data.Traversable.Traversable (Control.Applicative.ListF.MapF k f) instance Data.Foldable.Foldable f => Data.Foldable.Foldable (Control.Applicative.ListF.MapF k f) instance GHC.Base.Functor f => GHC.Base.Functor (Control.Applicative.ListF.MapF k f) instance forall k1 k2 (f :: k2 -> *) (a :: k2). (GHC.Classes.Ord k1, GHC.Classes.Ord (f a)) => GHC.Classes.Ord (Control.Applicative.ListF.MapF k1 f a) instance forall k1 k2 (f :: k2 -> *) (a :: k2). (GHC.Classes.Eq k1, GHC.Classes.Eq (f a)) => GHC.Classes.Eq (Control.Applicative.ListF.MapF k1 f a) instance forall k1 k2 (f :: k2 -> *) (a :: k2). (GHC.Classes.Ord k1, GHC.Read.Read k1, GHC.Read.Read (f a)) => GHC.Read.Read (Control.Applicative.ListF.MapF k1 f a) instance forall k1 k2 (f :: k2 -> *) (a :: k2). (GHC.Show.Show k1, GHC.Show.Show (f a)) => GHC.Show.Show (Control.Applicative.ListF.MapF k1 f a) instance Data.Functor.Classes.Ord1 f => Data.Functor.Classes.Ord1 (Control.Applicative.ListF.MaybeF f) instance GHC.Base.Applicative f => GHC.Base.Applicative (Control.Applicative.ListF.MaybeF f) instance GHC.Base.Functor f => Data.Functor.Alt.Alt (Control.Applicative.ListF.MaybeF f) instance GHC.Base.Functor f => Data.Functor.Plus.Plus (Control.Applicative.ListF.MaybeF f) instance GHC.Base.Applicative f => GHC.Base.Alternative (Control.Applicative.ListF.MaybeF f) instance forall k (f :: k -> *) (a :: k). GHC.Base.Semigroup (Control.Applicative.ListF.MaybeF f a) instance forall k (f :: k -> *) (a :: k). GHC.Base.Monoid (Control.Applicative.ListF.MaybeF f a) instance Data.Pointed.Pointed f => Data.Pointed.Pointed (Control.Applicative.ListF.MaybeF f) instance Data.Functor.Classes.Eq1 f => Data.Functor.Classes.Eq1 (Control.Applicative.ListF.MaybeF f) instance Data.Functor.Classes.Read1 f => Data.Functor.Classes.Read1 (Control.Applicative.ListF.MaybeF f) instance Data.Functor.Classes.Show1 f => Data.Functor.Classes.Show1 (Control.Applicative.ListF.MaybeF f) instance forall k (f :: k -> *) (a :: k). (Data.Typeable.Internal.Typeable a, Data.Typeable.Internal.Typeable f, Data.Typeable.Internal.Typeable k, Data.Data.Data (f a)) => Data.Data.Data (Control.Applicative.ListF.MaybeF f a) instance forall k (f :: k -> *) (a :: k). GHC.Generics.Generic (Control.Applicative.ListF.MaybeF f a) instance Data.Traversable.Traversable f => Data.Traversable.Traversable (Control.Applicative.ListF.MaybeF f) instance Data.Foldable.Foldable f => Data.Foldable.Foldable (Control.Applicative.ListF.MaybeF f) instance GHC.Base.Functor f => GHC.Base.Functor (Control.Applicative.ListF.MaybeF f) instance forall k (f :: k -> *) (a :: k). GHC.Classes.Ord (f a) => GHC.Classes.Ord (Control.Applicative.ListF.MaybeF f a) instance forall k (f :: k -> *) (a :: k). GHC.Classes.Eq (f a) => GHC.Classes.Eq (Control.Applicative.ListF.MaybeF f a) instance forall k (f :: k -> *) (a :: k). GHC.Read.Read (f a) => GHC.Read.Read (Control.Applicative.ListF.MaybeF f a) instance forall k (f :: k -> *) (a :: k). GHC.Show.Show (f a) => GHC.Show.Show (Control.Applicative.ListF.MaybeF f a) instance Data.Functor.Classes.Ord1 f => Data.Functor.Classes.Ord1 (Control.Applicative.ListF.NonEmptyF f) instance GHC.Base.Applicative f => GHC.Base.Applicative (Control.Applicative.ListF.NonEmptyF f) instance GHC.Base.Functor f => Data.Functor.Alt.Alt (Control.Applicative.ListF.NonEmptyF f) instance Data.Functor.Contravariant.Contravariant f => Data.Functor.Contravariant.Contravariant (Control.Applicative.ListF.NonEmptyF f) instance Data.Functor.Invariant.Invariant f => Data.Functor.Invariant.Invariant (Control.Applicative.ListF.NonEmptyF f) instance Data.Functor.Contravariant.Contravariant f => Data.Functor.Contravariant.Divise.Divise (Control.Applicative.ListF.NonEmptyF f) instance Data.Functor.Contravariant.Decide.Decide f => Data.Functor.Contravariant.Decide.Decide (Control.Applicative.ListF.NonEmptyF f) instance forall k (f :: k -> *) (a :: k). GHC.Base.Semigroup (Control.Applicative.ListF.NonEmptyF f a) instance Data.Pointed.Pointed f => Data.Pointed.Pointed (Control.Applicative.ListF.NonEmptyF f) instance Data.Functor.Classes.Eq1 f => Data.Functor.Classes.Eq1 (Control.Applicative.ListF.NonEmptyF f) instance Data.Functor.Classes.Read1 f => Data.Functor.Classes.Read1 (Control.Applicative.ListF.NonEmptyF f) instance Data.Functor.Classes.Show1 f => Data.Functor.Classes.Show1 (Control.Applicative.ListF.NonEmptyF f) instance forall k (f :: k -> *) (a :: k). (Data.Typeable.Internal.Typeable a, Data.Typeable.Internal.Typeable f, Data.Typeable.Internal.Typeable k, Data.Data.Data (f a)) => Data.Data.Data (Control.Applicative.ListF.NonEmptyF f a) instance forall k (f :: k -> *) (a :: k). GHC.Generics.Generic (Control.Applicative.ListF.NonEmptyF f a) instance Data.Traversable.Traversable f => Data.Traversable.Traversable (Control.Applicative.ListF.NonEmptyF f) instance Data.Foldable.Foldable f => Data.Foldable.Foldable (Control.Applicative.ListF.NonEmptyF f) instance GHC.Base.Functor f => GHC.Base.Functor (Control.Applicative.ListF.NonEmptyF f) instance forall k (f :: k -> *) (a :: k). GHC.Classes.Ord (f a) => GHC.Classes.Ord (Control.Applicative.ListF.NonEmptyF f a) instance forall k (f :: k -> *) (a :: k). GHC.Classes.Eq (f a) => GHC.Classes.Eq (Control.Applicative.ListF.NonEmptyF f a) instance forall k (f :: k -> *) (a :: k). GHC.Read.Read (f a) => GHC.Read.Read (Control.Applicative.ListF.NonEmptyF f a) instance forall k (f :: k -> *) (a :: k). GHC.Show.Show (f a) => GHC.Show.Show (Control.Applicative.ListF.NonEmptyF f a) instance Data.Functor.Classes.Ord1 f => Data.Functor.Classes.Ord1 (Control.Applicative.ListF.ListF f) instance Data.Functor.Bind.Class.Apply f => Data.Functor.Bind.Class.Apply (Control.Applicative.ListF.ListF f) instance GHC.Base.Applicative f => GHC.Base.Applicative (Control.Applicative.ListF.ListF f) instance GHC.Base.Functor f => Data.Functor.Alt.Alt (Control.Applicative.ListF.ListF f) instance GHC.Base.Functor f => Data.Functor.Plus.Plus (Control.Applicative.ListF.ListF f) instance GHC.Base.Applicative f => GHC.Base.Alternative (Control.Applicative.ListF.ListF f) instance forall k (f :: k -> *) (a :: k). GHC.Base.Semigroup (Control.Applicative.ListF.ListF f a) instance forall k (f :: k -> *) (a :: k). GHC.Base.Monoid (Control.Applicative.ListF.ListF f a) instance Data.Pointed.Pointed f => Data.Pointed.Pointed (Control.Applicative.ListF.ListF f) instance Data.Functor.Contravariant.Contravariant f => Data.Functor.Contravariant.Contravariant (Control.Applicative.ListF.ListF f) instance Data.Functor.Invariant.Invariant f => Data.Functor.Invariant.Invariant (Control.Applicative.ListF.ListF f) instance Data.Functor.Contravariant.Contravariant f => Data.Functor.Contravariant.Divise.Divise (Control.Applicative.ListF.ListF f) instance Data.Functor.Contravariant.Contravariant f => Data.Functor.Contravariant.Divisible.Divisible (Control.Applicative.ListF.ListF f) instance Data.Functor.Contravariant.Decide.Decide f => Data.Functor.Contravariant.Decide.Decide (Control.Applicative.ListF.ListF f) instance Data.Functor.Contravariant.Conclude.Conclude f => Data.Functor.Contravariant.Conclude.Conclude (Control.Applicative.ListF.ListF f) instance Data.Functor.Contravariant.Divisible.Decidable f => Data.Functor.Contravariant.Divisible.Decidable (Control.Applicative.ListF.ListF f) instance Data.Functor.Classes.Eq1 f => Data.Functor.Classes.Eq1 (Control.Applicative.ListF.ListF f) instance Data.Functor.Classes.Read1 f => Data.Functor.Classes.Read1 (Control.Applicative.ListF.ListF f) instance Data.Functor.Classes.Show1 f => Data.Functor.Classes.Show1 (Control.Applicative.ListF.ListF f) instance forall k (f :: k -> *) (a :: k). (Data.Typeable.Internal.Typeable a, Data.Typeable.Internal.Typeable f, Data.Typeable.Internal.Typeable k, Data.Data.Data (f a)) => Data.Data.Data (Control.Applicative.ListF.ListF f a) instance forall k (f :: k -> *) (a :: k). GHC.Generics.Generic (Control.Applicative.ListF.ListF f a) instance Data.Traversable.Traversable f => Data.Traversable.Traversable (Control.Applicative.ListF.ListF f) instance Data.Foldable.Foldable f => Data.Foldable.Foldable (Control.Applicative.ListF.ListF f) instance GHC.Base.Functor f => GHC.Base.Functor (Control.Applicative.ListF.ListF f) instance forall k (f :: k -> *) (a :: k). GHC.Classes.Ord (f a) => GHC.Classes.Ord (Control.Applicative.ListF.ListF f a) instance forall k (f :: k -> *) (a :: k). GHC.Classes.Eq (f a) => GHC.Classes.Eq (Control.Applicative.ListF.ListF f a) instance forall k (f :: k -> *) (a :: k). GHC.Read.Read (f a) => GHC.Read.Read (Control.Applicative.ListF.ListF f a) instance forall k (f :: k -> *) (a :: k). GHC.Show.Show (f a) => GHC.Show.Show (Control.Applicative.ListF.ListF f a) -- | Provides Night, a form of the day convolution that is -- contravariant and splits on Either. module Data.Functor.Contravariant.Night -- | A pairing of contravariant functors to create a new contravariant -- functor that represents the "choice" between the two. -- -- A Night f g a is a contravariant "consumer" of -- a, and it does this by either feeding the a to -- f, or feeding the a to g. Which one it -- gives it to happens at runtime depending what a is -- actually given. -- -- For example, if we have x :: f a (a consumer of as) -- and y :: g b (a consumer of bs), then -- night x y :: Night f g (Either a b). -- This is a consumer of Either a bs, and it consumes -- Left branches by feeding it to x, and Right -- branches by feeding it to y. -- -- Mathematically, this is a contravariant day convolution, except with a -- different choice of bifunctor (Either) than the typical one we -- talk about in Haskell (which uses (,)). Therefore, it is an -- alternative to the typical Day convolution --- hence, the name -- Night. data Night :: (Type -> Type) -> (Type -> Type) -> (Type -> Type) [Night] :: f b -> g c -> (a -> Either b c) -> Night f g a -- | Inject into a Night. -- -- night x y is a consumer of Either a b; -- Left will be passed to x, and Right will be -- passed to y. night :: f a -> g b -> Night f g (Either a b) -- | Interpret out of a Night into any instance of Decide by -- providing two interpreting functions. runNight :: Decide h => (f ~> h) -> (g ~> h) -> Night f g ~> h -- | Night is associative. assoc :: Night f (Night g h) ~> Night (Night f g) h -- | Night is associative. unassoc :: Night (Night f g) h ~> Night f (Night g h) -- | The two sides of a Night can be swapped. swapped :: Night f g ~> Night g f -- | Hoist a function over the left side of a Night. trans1 :: (f ~> h) -> Night f g ~> Night h g -- | Hoist a function over the right side of a Night. trans2 :: (g ~> h) -> Night f g ~> Night f h -- | The left identity of Night is Not; this is one side of -- that isomorphism. intro1 :: g ~> Night Not g -- | The right identity of Night is Not; this is one side of -- that isomorphism. intro2 :: f ~> Night f Not -- | The left identity of Night is Not; this is one side of -- that isomorphism. elim1 :: Contravariant g => Night Not g ~> g -- | The right identity of Night is Not; this is one side of -- that isomorphism. elim2 :: Contravariant f => Night f Not ~> f -- | A value of type Not a is "proof" that a is -- uninhabited. newtype Not a Not :: (a -> Void) -> Not a [refute] :: Not a -> a -> Void instance Data.Functor.Contravariant.Contravariant Data.Functor.Contravariant.Night.Not instance GHC.Base.Semigroup (Data.Functor.Contravariant.Night.Not a) instance Data.Functor.Contravariant.Contravariant (Data.Functor.Contravariant.Night.Night f g) instance Data.Functor.Invariant.Invariant (Data.Functor.Contravariant.Night.Night f g) -- | This module provides abstractions for working with unary functor -- combinators. -- -- Principally, it defines the HFunctor itself, as well as some -- classes that expose extra functionality that some HFunctors -- have (Inject and HBind). -- -- See Data.HFunctor.Interpret for tools to use HFunctors -- as functor combinators that can represent interpretable schemas, and -- Data.HBifunctor for an abstraction over binary functor -- combinators. module Data.HFunctor -- | An HFunctor can be thought of a unary "functor transformer" --- -- a basic functor combinator. It takes a functor as input and returns a -- functor as output. -- -- It "enhances" a functor with extra structure (sort of like how a monad -- transformer enhances a Monad with extra structure). -- -- As a uniform inteface, we can "swap the underlying functor" (also -- sometimes called "hoisting"). This is what hmap does: it lets -- us swap out the f in a t f for a t g. -- -- For example, the free monad Free takes a Functor and -- returns a new Functor. In the process, it provides a monadic -- structure over f. hmap lets us turn a Free -- f into a Free g: a monad built over f -- can be turned into a monad built over g. -- -- For the ability to move in and out of the enhanced functor, see -- Inject and Interpret. -- -- This class is similar to MFunctor from -- Control.Monad.Morph, but instances must work without a -- Monad constraint. -- -- This class is also found in the hschema library with the same -- name. class HFunctor t -- | If we can turn an f into a g, then we can turn a -- t f into a t g. -- -- It must be the case that -- --
-- hmap id == id ---- -- Essentially, t f adds some "extra structure" to f. -- hmap must swap out the functor, without affecting the added -- structure. -- -- For example, ListF f a is essentially a list of f -- as. If we hmap to swap out the f as for g -- as, then we must ensure that the "added structure" (here, the -- number of items in the list, and the ordering of those items) remains -- the same. So, hmap must preserve the number of items in the -- list, and must maintain the ordering. -- -- The law hmap id == id is a way of formalizing -- this property. hmap :: HFunctor t => (f ~> g) -> t f ~> t g -- | Lift an isomorphism over an HFunctor. -- -- Essentailly, if f and g are isomorphic, then so are -- t f and t g. overHFunctor :: HFunctor t => (f <~> g) -> t f <~> t g -- | A typeclass for HFunctors where you can "inject" an f -- a into a t f a: -- --
-- inject :: f a -> t f a ---- -- If you think of t f a as an "enhanced f", then -- inject allows you to use an f as its enhanced form. -- -- With the exception of directly pattern matching on the result, -- inject itself is not too useful in the general case without -- Interpret to allow us to interpret or retrieve back the -- f. class HFunctor t => Inject t -- | Lift from f into the enhanced t f structure. -- Analogous to lift from MonadTrans. -- -- Note that this lets us "lift" a f a; if you want to lift an -- a with a -> t f a, check if t f is an -- instance of Applicative or Pointed. inject :: Inject t => f ~> t f -- | HBind is effectively a "higher-order Monad", in the -- sense that HFunctor is a "higher-order Functor". -- -- It can be considered a typeclass for HFunctors that you can -- bind continuations to, nautraluniversal over all -- ffunctors. They work "for all functors" you lift, without -- requiring any constraints. -- -- It is very similar to Interpret, except Interpret has -- the ability to constrain the contexts to some typeclass. -- -- The main law is that binding inject should leave things -- unchanged: -- --
-- hbind inject == id ---- -- But hbind should also be associatiatve, in a way that makes -- --
-- hjoin . hjoin -- = hjoin . hmap hjoin ---- -- That is, squishing a t (t (t f)) a into a t f a can -- be done "inside" first, then "outside", or "outside" first, then -- "inside". -- -- Note that these laws are different from the Interpret laws, so -- we often have instances where hbind and interpret -- (though they both may typecheck) produce different behavior. -- -- This class is similar to MMonad from -- Control.Monad.Morph, but instances must work without a -- Monad constraint. class Inject t => HBind t -- | Bind a continuation to a t f into some context g. hbind :: HBind t => (f ~> t g) -> t f ~> t g -- | Collapse a nested t (t f) into a single t f. hjoin :: HBind t => t (t f) ~> t f -- | The functor combinator that forgets all structure in the input. -- Ignores the input structure and stores no information. -- -- Acts like the "zero" with respect to functor combinator composition. -- --
-- ComposeT ProxyF f ~ ProxyF -- ComposeT f ProxyF ~ ProxyF ---- -- It can be injected into (losing all information), but it is -- impossible to ever retract or interpret it. -- -- This is essentially ConstF (). data ProxyF f a ProxyF :: ProxyF f a -- | Functor combinator that forgets all structure on the input, and -- instead stores a value of type e. -- -- Like ProxyF, acts like a "zero" with functor combinator -- composition. -- -- It can be injected into (losing all information), but it is -- impossible to ever retract or interpret it. data ConstF e f a ConstF :: e -> ConstF e f a [getConstF] :: ConstF e f a -> e -- | An "HFunctor combinator" that enhances an HFunctor with -- the ability to hold a single f a. This is the higher-order -- analogue of Lift. -- -- You can think of it as a free Inject for any f. -- -- Note that HLift IdentityT is equivalent to -- EnvT Any. data HLift t f a HPure :: f a -> HLift t f a HOther :: t f a -> HLift t f a -- | A higher-level retract to get a t f a back out of an -- HLift t f a, provided t is an instance of -- Inject. -- -- This witnesses the fact that HLift is the "Free Inject". retractHLift :: Inject t => HLift t f a -> t f a -- | An "HFunctor combinator" that turns an HFunctor into -- potentially infinite nestings of that HFunctor. -- -- An HFree t f a is either f a, t f a, -- t (t f) a, t (t (t f)) a, etc. -- -- This effectively turns t into a tree with t -- branches. -- -- One particularly useful usage is with MapF. For example if you -- had a data type representing a command line command parser: -- --
-- data Command a ---- -- You could represent "many possible named commands" using -- --
-- type Commands = MapF String Command ---- -- And you can represent multiple nested named commands using: -- --
-- type NestedCommands = HFree (MapF String) ---- -- This has an Interpret instance, but it can be more useful to -- use via direct pattern matching, or through -- --
-- foldHFree -- :: HBifunctor t -- => f ~> g -- -> t g ~> g -- -> HFree t f ~> g ---- -- which requires no extra constriant on g, and lets you -- consider each branch separately. -- -- This can be considered the higher-oder analogue of Free; it is -- the free HBind for any HFunctor t. -- -- Note that HFree IdentityT is equivalent to -- Step. data HFree t f a HReturn :: f a -> HFree t f a HJoin :: t (HFree t f) a -> HFree t f a -- | Recursively fold down an HFree into a single g result, -- by handling each branch. Can be more useful than interpret -- because it allows you to treat each branch separately, and also does -- not require any constraint on g. -- -- This is the catamorphism on HFree. foldHFree :: forall t f g. HFunctor t => (f ~> g) -> (t g ~> g) -> HFree t f ~> g -- | A higher-level retract to get a t f a back out of an -- HFree t f a, provided t is an instance of -- Bind. -- -- This witnesses the fact that HFree is the "Free Bind". retractHFree :: HBind t => HFree t f a -> t f a instance (GHC.Base.Functor f, GHC.Base.Functor (t f)) => GHC.Base.Functor (Data.HFunctor.HLift t f) instance forall k (f :: k -> *) (a :: k) (t :: (k -> *) -> k -> *). (GHC.Show.Show (f a), GHC.Show.Show (t f a)) => GHC.Show.Show (Data.HFunctor.HLift t f a) instance forall k (f :: k -> *) (a :: k) (t :: (k -> *) -> k -> *). (GHC.Read.Read (f a), GHC.Read.Read (t f a)) => GHC.Read.Read (Data.HFunctor.HLift t f a) instance forall k (f :: k -> *) (a :: k) (t :: (k -> *) -> k -> *). (GHC.Classes.Eq (f a), GHC.Classes.Eq (t f a)) => GHC.Classes.Eq (Data.HFunctor.HLift t f a) instance forall k (f :: k -> *) (a :: k) (t :: (k -> *) -> k -> *). (GHC.Classes.Ord (f a), GHC.Classes.Ord (t f a)) => GHC.Classes.Ord (Data.HFunctor.HLift t f a) instance (GHC.Base.Functor f, GHC.Base.Functor (t (Data.HFunctor.HFree t f))) => GHC.Base.Functor (Data.HFunctor.HFree t f) instance Data.HFunctor.HBind Data.Functor.Coyoneda.Coyoneda instance Data.HFunctor.HBind Control.Applicative.Free.Ap instance Data.HFunctor.HBind Control.Applicative.ListF.ListF instance Data.HFunctor.HBind Control.Applicative.ListF.NonEmptyF instance Data.HFunctor.HBind Control.Applicative.ListF.MaybeF instance Data.HFunctor.HBind Control.Applicative.Step.Step instance Data.HFunctor.HBind Control.Applicative.Step.Flagged instance Data.Functor.Alt.Alt f => Data.HFunctor.HBind (Data.Functor.These.These1 f) instance Data.Functor.Plus.Plus f => Data.HFunctor.HBind ((GHC.Generics.:*:) f) instance Data.Functor.Plus.Plus f => Data.HFunctor.HBind (Data.Functor.Product.Product f) instance forall k (f :: k -> *). Data.HFunctor.HBind ((GHC.Generics.:+:) f) instance forall k (f :: k -> *). Data.HFunctor.HBind (Data.Functor.Sum.Sum f) instance Data.HFunctor.HBind (GHC.Generics.M1 i c) instance Data.HFunctor.HBind Control.Alternative.Free.Alt instance Data.HFunctor.HBind Control.Monad.Freer.Church.Free instance Data.HFunctor.HBind Control.Monad.Freer.Church.Free1 instance Data.HFunctor.HBind Control.Applicative.Free.Final.Ap instance Data.HFunctor.HBind Control.Applicative.Free.Fast.Ap instance Data.HFunctor.HBind Control.Monad.Trans.Identity.IdentityT instance Data.HFunctor.HBind Control.Applicative.Lift.Lift instance Data.HFunctor.HBind Data.Functor.Bind.Class.MaybeApply instance Data.HFunctor.HBind Control.Applicative.Backwards.Backwards instance Data.HFunctor.HBind Data.Functor.Bind.Class.WrappedApplicative instance Data.HFunctor.HBind Data.Functor.Reverse.Reverse instance Data.HFunctor.HBind Data.HFunctor.ProxyF instance GHC.Base.Monoid e => Data.HFunctor.HBind (Control.Comonad.Trans.Env.EnvT e) instance forall k (t :: (k -> *) -> k -> *). (Data.HFunctor.HBind t, Data.HFunctor.Inject t) => Data.HFunctor.HBind (Data.HFunctor.HLift t) instance forall k (t :: (k -> *) -> k -> *). Data.HFunctor.Internal.HFunctor t => Data.HFunctor.HBind (Data.HFunctor.HFree t) instance Data.HFunctor.Inject Data.Functor.Coyoneda.Coyoneda instance Data.HFunctor.Inject Data.Functor.Contravariant.Coyoneda.Coyoneda instance Data.HFunctor.Inject Control.Applicative.Free.Ap instance Data.HFunctor.Inject Control.Applicative.ListF.ListF instance Data.HFunctor.Inject Control.Applicative.ListF.NonEmptyF instance Data.HFunctor.Inject Control.Applicative.ListF.MaybeF instance GHC.Base.Monoid k2 => Data.HFunctor.Inject (Control.Applicative.ListF.NEMapF k2) instance GHC.Base.Monoid k2 => Data.HFunctor.Inject (Control.Applicative.ListF.MapF k2) instance Data.HFunctor.Inject Control.Applicative.Step.Step instance Data.HFunctor.Inject Control.Applicative.Step.Steps instance Data.HFunctor.Inject Control.Applicative.Step.Flagged instance Data.HFunctor.Inject (Data.Functor.These.These1 f) instance GHC.Base.Applicative f => Data.HFunctor.Inject (Control.Monad.Freer.Church.Comp f) instance GHC.Base.Applicative f => Data.HFunctor.Inject ((GHC.Generics.:.:) f) instance Data.Functor.Plus.Plus f => Data.HFunctor.Inject ((GHC.Generics.:*:) f) instance Data.Functor.Plus.Plus f => Data.HFunctor.Inject (Data.Functor.Product.Product f) instance forall k (f :: k -> *). Data.HFunctor.Inject ((GHC.Generics.:+:) f) instance forall k (f :: k -> *). Data.HFunctor.Inject (Data.Functor.Sum.Sum f) instance Data.HFunctor.Inject (GHC.Generics.M1 i c) instance Data.HFunctor.Inject Control.Alternative.Free.Alt instance Data.HFunctor.Inject Control.Monad.Freer.Church.Free instance Data.HFunctor.Inject Control.Monad.Freer.Church.Free1 instance Data.HFunctor.Inject Control.Applicative.Free.Final.Ap instance Data.HFunctor.Inject Control.Applicative.Free.Fast.Ap instance Data.HFunctor.Inject Control.Monad.Trans.Identity.IdentityT instance Data.HFunctor.Inject Control.Applicative.Lift.Lift instance Data.HFunctor.Inject Data.Functor.Bind.Class.MaybeApply instance Data.HFunctor.Inject Control.Applicative.Backwards.Backwards instance Data.HFunctor.Inject Data.Functor.Bind.Class.WrappedApplicative instance Data.HFunctor.Inject (Control.Monad.Trans.Reader.ReaderT r) instance GHC.Base.Monoid e => Data.HFunctor.Inject (Control.Comonad.Trans.Env.EnvT e) instance Data.HFunctor.Inject Data.Functor.Reverse.Reverse instance Data.HFunctor.Inject Data.HFunctor.ProxyF instance GHC.Base.Monoid e => Data.HFunctor.Inject (Data.HFunctor.ConstF e) instance (Data.HFunctor.Inject s, Data.HFunctor.Inject t) => Data.HFunctor.Inject (Control.Monad.Trans.Compose.ComposeT s t) instance forall k (t :: (k -> *) -> k -> *). Data.HFunctor.Internal.HFunctor t => Data.HFunctor.Inject (Data.HFunctor.HLift t) instance forall k (t :: (k -> *) -> k -> *). Data.HFunctor.Internal.HFunctor t => Data.HFunctor.Inject (Data.HFunctor.HFree t) instance (Data.Functor.Contravariant.Contravariant f, Data.Functor.Contravariant.Contravariant (t (Data.HFunctor.HFree t f))) => Data.Functor.Contravariant.Contravariant (Data.HFunctor.HFree t f) instance (Data.Functor.Invariant.Invariant f, Data.Functor.Invariant.Invariant (t (Data.HFunctor.HFree t f))) => Data.Functor.Invariant.Invariant (Data.HFunctor.HFree t f) instance (Data.Functor.Classes.Show1 (t (Data.HFunctor.HFree t f)), Data.Functor.Classes.Show1 f) => Data.Functor.Classes.Show1 (Data.HFunctor.HFree t f) instance (Data.Functor.Classes.Show1 (t (Data.HFunctor.HFree t f)), Data.Functor.Classes.Show1 f, GHC.Show.Show a) => GHC.Show.Show (Data.HFunctor.HFree t f a) instance forall k (t :: (k -> *) -> k -> *). Data.HFunctor.Internal.HFunctor t => Data.HFunctor.Internal.HFunctor (Data.HFunctor.HFree t) instance (Data.Functor.Classes.Show1 (t f), Data.Functor.Classes.Show1 f) => Data.Functor.Classes.Show1 (Data.HFunctor.HLift t f) instance (Data.Functor.Classes.Eq1 (t f), Data.Functor.Classes.Eq1 f) => Data.Functor.Classes.Eq1 (Data.HFunctor.HLift t f) instance (Data.Functor.Classes.Ord1 (t f), Data.Functor.Classes.Ord1 f) => Data.Functor.Classes.Ord1 (Data.HFunctor.HLift t f) instance forall k (t :: (k -> *) -> k -> *). Data.HFunctor.Internal.HFunctor t => Data.HFunctor.Internal.HFunctor (Data.HFunctor.HLift t) instance (Data.Functor.Contravariant.Contravariant f, Data.Functor.Contravariant.Contravariant (t f)) => Data.Functor.Contravariant.Contravariant (Data.HFunctor.HLift t f) instance (Data.Functor.Invariant.Invariant f, Data.Functor.Invariant.Invariant (t f)) => Data.Functor.Invariant.Invariant (Data.HFunctor.HLift t f) instance forall k e (f :: k). GHC.Classes.Ord e => Data.Functor.Classes.Ord1 (Data.HFunctor.ConstF e f) instance forall k e (f :: k). Data.Functor.Contravariant.Contravariant (Data.HFunctor.ConstF e f) instance forall k e (f :: k). GHC.Base.Monoid e => Data.Functor.Contravariant.Divisible.Divisible (Data.HFunctor.ConstF e f) instance forall k e (f :: k). GHC.Base.Semigroup e => Data.Functor.Contravariant.Divise.Divise (Data.HFunctor.ConstF e f) instance forall k e (f :: k). Data.Functor.Invariant.Invariant (Data.HFunctor.ConstF e f) instance Data.HFunctor.Internal.HFunctor (Data.HFunctor.ConstF e) instance forall k e (f :: k). GHC.Classes.Eq e => Data.Functor.Classes.Eq1 (Data.HFunctor.ConstF e f) instance forall k e (f :: k). GHC.Read.Read e => Data.Functor.Classes.Read1 (Data.HFunctor.ConstF e f) instance forall k e (f :: k). GHC.Show.Show e => Data.Functor.Classes.Show1 (Data.HFunctor.ConstF e f) instance forall e k1 (f :: k1) k2 (a :: k2). (Data.Typeable.Internal.Typeable f, Data.Typeable.Internal.Typeable a, Data.Typeable.Internal.Typeable k1, Data.Typeable.Internal.Typeable k2, Data.Data.Data e) => Data.Data.Data (Data.HFunctor.ConstF e f a) instance forall e k1 (f :: k1) k2 (a :: k2). GHC.Generics.Generic (Data.HFunctor.ConstF e f a) instance forall e k (f :: k). Data.Traversable.Traversable (Data.HFunctor.ConstF e f) instance forall e k (f :: k). Data.Foldable.Foldable (Data.HFunctor.ConstF e f) instance forall e k (f :: k). GHC.Base.Functor (Data.HFunctor.ConstF e f) instance forall e k1 (f :: k1) k2 (a :: k2). GHC.Classes.Ord e => GHC.Classes.Ord (Data.HFunctor.ConstF e f a) instance forall e k1 (f :: k1) k2 (a :: k2). GHC.Classes.Eq e => GHC.Classes.Eq (Data.HFunctor.ConstF e f a) instance forall e k1 (f :: k1) k2 (a :: k2). GHC.Read.Read e => GHC.Read.Read (Data.HFunctor.ConstF e f a) instance forall e k1 (f :: k1) k2 (a :: k2). GHC.Show.Show e => GHC.Show.Show (Data.HFunctor.ConstF e f a) instance forall k (f :: k). Data.Functor.Classes.Ord1 (Data.HFunctor.ProxyF f) instance forall k (f :: k). Data.Functor.Contravariant.Contravariant (Data.HFunctor.ProxyF f) instance forall k (f :: k). Data.Functor.Contravariant.Divisible.Divisible (Data.HFunctor.ProxyF f) instance forall k (f :: k). Data.Functor.Contravariant.Divise.Divise (Data.HFunctor.ProxyF f) instance forall k (f :: k). Data.Functor.Contravariant.Decide.Decide (Data.HFunctor.ProxyF f) instance forall k (f :: k). Data.Functor.Contravariant.Conclude.Conclude (Data.HFunctor.ProxyF f) instance forall k (f :: k). Data.Functor.Contravariant.Divisible.Decidable (Data.HFunctor.ProxyF f) instance forall k (f :: k). Data.Functor.Invariant.Invariant (Data.HFunctor.ProxyF f) instance Data.HFunctor.Internal.HFunctor Data.HFunctor.ProxyF instance forall k (f :: k). Data.Functor.Classes.Eq1 (Data.HFunctor.ProxyF f) instance forall k (f :: k). Data.Functor.Classes.Read1 (Data.HFunctor.ProxyF f) instance forall k (f :: k). Data.Functor.Classes.Show1 (Data.HFunctor.ProxyF f) instance forall k1 (f :: k1) k2 (a :: k2). (Data.Typeable.Internal.Typeable f, Data.Typeable.Internal.Typeable a, Data.Typeable.Internal.Typeable k1, Data.Typeable.Internal.Typeable k2) => Data.Data.Data (Data.HFunctor.ProxyF f a) instance forall k1 (f :: k1) k2 (a :: k2). GHC.Generics.Generic (Data.HFunctor.ProxyF f a) instance forall k (f :: k). Data.Traversable.Traversable (Data.HFunctor.ProxyF f) instance forall k (f :: k). Data.Foldable.Foldable (Data.HFunctor.ProxyF f) instance forall k (f :: k). GHC.Base.Functor (Data.HFunctor.ProxyF f) instance forall k1 (f :: k1) k2 (a :: k2). GHC.Classes.Ord (Data.HFunctor.ProxyF f a) instance forall k1 (f :: k1) k2 (a :: k2). GHC.Classes.Eq (Data.HFunctor.ProxyF f a) instance forall k1 (f :: k1) k2 (a :: k2). GHC.Read.Read (Data.HFunctor.ProxyF f a) instance forall k1 (f :: k1) k2 (a :: k2). GHC.Show.Show (Data.HFunctor.ProxyF f a) -- | This module provides tools for working with unary functor combinators -- that represent interpretable schemas. -- -- These are types t that take a functor f and return a -- new functor t f, enhancing f with new structure and -- abilities. -- -- For these, we have: -- --
-- inject :: f a -> t f a ---- -- which lets you "lift" an f a into its transformed version, -- and also: -- --
-- interpret -- :: C t g -- => (forall x. f a -> g a) -- -> t f a -- -> g a ---- -- that lets you "interpret" a t f a into a context g -- a, essentially "running" the computaiton that it encodes. The -- context is required to have a typeclass constraints that reflects what -- is "required" to be able to run a functor combinator. -- -- Every single instance provides different tools. Check out the instance -- list for a nice list of useful combinators, or also the README for a -- high-level rundown. -- -- See Data.Functor.Tensor for binary functor combinators that mix -- together two or more different functors. module Data.HFunctor.Interpret -- | An Interpret lets us move in and out of the "enhanced" -- Functor (t f) and the functor it enhances -- (f). An instance Interpret t f means we have -- t f a -> f a. -- -- For example, Free f is f enhanced with -- monadic structure. We get: -- --
-- inject :: f a -> Free f a -- interpret :: Monad m => (forall x. f x -> m x) -> Free f a -> m a ---- -- inject will let us use our f inside the enhanced -- Free f. interpret will let us "extract" the -- f from a Free f if we can give an -- interpreting function that interprets f into some -- target Monad. -- -- We enforce that: -- --
-- interpret id . inject == id -- -- or -- retract . inject == id ---- -- That is, if we lift a value into our structure, then immediately -- interpret it out as itself, it should lave the value unchanged. -- -- Note that instances of this class are intended to be written -- with t as a fixed type constructor, and f to be -- allowed to vary freely: -- --
-- instance Monad f => Interpret Free f ---- -- Any other sort of instance and it's easy to run into problems with -- type inference. If you want to write an instance that's "polymorphic" -- on tensor choice, use the WrapHF newtype wrapper over a type -- variable, where the second argument also uses a type constructor: -- --
-- instance Interpret (WrapHF t) (MyFunctor t) ---- -- This will prevent problems with overloaded instances. class Inject t => Interpret t f -- | Remove the f out of the enhanced t f structure, -- provided that f satisfies the necessary constraints. If it -- doesn't, it needs to be properly interpreted out. retract :: Interpret t f => t f ~> f -- | Given an "interpeting function" from f to g, -- interpret the f out of the t f into a final context -- g. interpret :: Interpret t f => (g ~> f) -> t g ~> f -- | A convenient flipped version of interpret. forI :: Interpret t f => t g a -> (g ~> f) -> f a -- | Useful wrapper over interpret to allow you to directly extract -- a value b out of the t f a, if you can convert f -- x into b. -- -- Note that depending on the constraints on f in -- Interpret t f, you may have extra constraints on -- b. -- --
-- -- get the length of the Map String in the Step. -- collectI length -- :: Step (Map String) Bool -- -> Int --getI :: Interpret t (Const b) => (forall x. f x -> b) -> t f a -> b -- | Useful wrapper over getI to allow you to collect a b -- from all instances of f inside a t f a. -- -- Will work if there is an instance of Interpret t -- (Const [b]), which will be the case if the constraint on -- the target functor is Functor, Apply, -- Applicative, or unconstrianed. -- --
-- -- get the lengths of all Map Strings in the Ap. -- collectI length -- :: Ap (Map String) Bool -- -> [Int] --collectI :: Interpret t (Const [b]) => (forall x. f x -> b) -> t f a -> [b] -- | A constraint on a for both c a and d a. -- Requiring AndC Show Eq a is the same as -- requiring (Show a, Eq a). class (c a, d a) => AndC c d a -- | A newtype wrapper meant to be used to define polymorphic -- Interpret instances. See documentation for Interpret for -- more information. -- -- Please do not ever define an instance of Interpret "naked" on -- the second parameter: -- --
-- instance Interpret (WrapHF t) f ---- -- As that would globally ruin everything using WrapHF. newtype WrapHF t f a WrapHF :: t f a -> WrapHF t f a [unwrapHF] :: WrapHF t f a -> t f a instance forall k1 k2 (t :: k1 -> k2 -> *) (f :: k1) (a :: k2). (Data.Typeable.Internal.Typeable f, Data.Typeable.Internal.Typeable a, Data.Typeable.Internal.Typeable t, Data.Typeable.Internal.Typeable k1, Data.Typeable.Internal.Typeable k2, Data.Data.Data (t f a)) => Data.Data.Data (Data.HFunctor.Interpret.WrapHF t f a) instance forall k1 k2 (t :: k1 -> k2 -> *) (f :: k1) (a :: k2). GHC.Generics.Generic (Data.HFunctor.Interpret.WrapHF t f a) instance forall k (t :: k -> * -> *) (f :: k). Data.Traversable.Traversable (t f) => Data.Traversable.Traversable (Data.HFunctor.Interpret.WrapHF t f) instance forall k (t :: k -> * -> *) (f :: k). Data.Foldable.Foldable (t f) => Data.Foldable.Foldable (Data.HFunctor.Interpret.WrapHF t f) instance forall k (t :: k -> * -> *) (f :: k). GHC.Base.Functor (t f) => GHC.Base.Functor (Data.HFunctor.Interpret.WrapHF t f) instance forall k1 k2 (t :: k1 -> k2 -> *) (f :: k1) (a :: k2). GHC.Classes.Ord (t f a) => GHC.Classes.Ord (Data.HFunctor.Interpret.WrapHF t f a) instance forall k1 k2 (t :: k1 -> k2 -> *) (f :: k1) (a :: k2). GHC.Classes.Eq (t f a) => GHC.Classes.Eq (Data.HFunctor.Interpret.WrapHF t f a) instance forall k1 k2 (t :: k1 -> k2 -> *) (f :: k1) (a :: k2). GHC.Read.Read (t f a) => GHC.Read.Read (Data.HFunctor.Interpret.WrapHF t f a) instance forall k1 k2 (t :: k1 -> k2 -> *) (f :: k1) (a :: k2). GHC.Show.Show (t f a) => GHC.Show.Show (Data.HFunctor.Interpret.WrapHF t f a) instance forall k (t :: k -> * -> *) (f :: k). Data.Functor.Classes.Show1 (t f) => Data.Functor.Classes.Show1 (Data.HFunctor.Interpret.WrapHF t f) instance forall k (t :: k -> * -> *) (f :: k). Data.Functor.Classes.Eq1 (t f) => Data.Functor.Classes.Eq1 (Data.HFunctor.Interpret.WrapHF t f) instance forall k (t :: k -> * -> *) (f :: k). Data.Functor.Classes.Ord1 (t f) => Data.Functor.Classes.Ord1 (Data.HFunctor.Interpret.WrapHF t f) instance forall k1 k2 (t :: (k1 -> *) -> k2 -> *). Data.HFunctor.Internal.HFunctor t => Data.HFunctor.Internal.HFunctor (Data.HFunctor.Interpret.WrapHF t) instance forall k (t :: (k -> *) -> k -> *). Data.HFunctor.Inject t => Data.HFunctor.Inject (Data.HFunctor.Interpret.WrapHF t) instance forall k (t :: (k -> *) -> k -> *). Data.HFunctor.HBind t => Data.HFunctor.HBind (Data.HFunctor.Interpret.WrapHF t) instance forall k (c :: k -> GHC.Types.Constraint) (a :: k) (d :: k -> GHC.Types.Constraint). (c a, d a) => Data.HFunctor.Interpret.AndC c d a instance GHC.Base.Functor f => Data.HFunctor.Interpret.Interpret Data.Functor.Coyoneda.Coyoneda f instance Data.Functor.Contravariant.Contravariant f => Data.HFunctor.Interpret.Interpret Data.Functor.Contravariant.Coyoneda.Coyoneda f instance GHC.Base.Applicative f => Data.HFunctor.Interpret.Interpret Control.Applicative.Free.Ap f instance Data.Functor.Plus.Plus f => Data.HFunctor.Interpret.Interpret Control.Applicative.ListF.ListF f instance Data.Functor.Alt.Alt f => Data.HFunctor.Interpret.Interpret Control.Applicative.ListF.NonEmptyF f instance Data.Functor.Plus.Plus f => Data.HFunctor.Interpret.Interpret Control.Applicative.ListF.MaybeF f instance (GHC.Base.Monoid k, Data.Functor.Plus.Plus f) => Data.HFunctor.Interpret.Interpret (Control.Applicative.ListF.MapF k) f instance (GHC.Base.Monoid k, Data.Functor.Alt.Alt f) => Data.HFunctor.Interpret.Interpret (Control.Applicative.ListF.NEMapF k) f instance forall k (f :: k -> *). Data.HFunctor.Interpret.Interpret Control.Applicative.Step.Step f instance Data.Functor.Alt.Alt f => Data.HFunctor.Interpret.Interpret Control.Applicative.Step.Steps f instance forall k (f :: k -> *). Data.HFunctor.Interpret.Interpret Control.Applicative.Step.Flagged f instance Data.Functor.Plus.Plus f => Data.HFunctor.Interpret.Interpret (Data.Functor.These.These1 g) f instance GHC.Base.Alternative f => Data.HFunctor.Interpret.Interpret Control.Alternative.Free.Alt f instance Data.Functor.Plus.Plus g => Data.HFunctor.Interpret.Interpret ((GHC.Generics.:*:) g) f instance Data.Functor.Plus.Plus g => Data.HFunctor.Interpret.Interpret (Data.Functor.Product.Product g) f instance Data.Functor.Plus.Plus f => Data.HFunctor.Interpret.Interpret ((GHC.Generics.:+:) g) f instance Data.Functor.Plus.Plus f => Data.HFunctor.Interpret.Interpret (Data.Functor.Sum.Sum g) f instance forall k i (c :: GHC.Generics.Meta) (f :: k -> *). Data.HFunctor.Interpret.Interpret (GHC.Generics.M1 i c) f instance GHC.Base.Monad f => Data.HFunctor.Interpret.Interpret Control.Monad.Freer.Church.Free f instance Data.Functor.Bind.Class.Bind f => Data.HFunctor.Interpret.Interpret Control.Monad.Freer.Church.Free1 f instance GHC.Base.Applicative f => Data.HFunctor.Interpret.Interpret Control.Applicative.Free.Final.Ap f instance GHC.Base.Applicative f => Data.HFunctor.Interpret.Interpret Control.Applicative.Free.Fast.Ap f instance forall k (f :: k -> *). Data.HFunctor.Interpret.Interpret Control.Monad.Trans.Identity.IdentityT f instance Data.Pointed.Pointed f => Data.HFunctor.Interpret.Interpret Control.Applicative.Lift.Lift f instance Data.Pointed.Pointed f => Data.HFunctor.Interpret.Interpret Data.Functor.Bind.Class.MaybeApply f instance forall k (f :: k -> *). Data.HFunctor.Interpret.Interpret Control.Applicative.Backwards.Backwards f instance Data.HFunctor.Interpret.Interpret Data.Functor.Bind.Class.WrappedApplicative f instance Control.Monad.Reader.Class.MonadReader r f => Data.HFunctor.Interpret.Interpret (Control.Monad.Trans.Reader.ReaderT r) f instance GHC.Base.Monoid e => Data.HFunctor.Interpret.Interpret (Control.Comonad.Trans.Env.EnvT e) f instance forall k (f :: k -> *). Data.HFunctor.Interpret.Interpret Data.Functor.Reverse.Reverse f instance (Data.HFunctor.Interpret.Interpret s f, Data.HFunctor.Interpret.Interpret t f) => Data.HFunctor.Interpret.Interpret (Control.Monad.Trans.Compose.ComposeT s t) f instance forall k (t :: (k -> *) -> k -> *) (f :: k -> *). Data.HFunctor.Interpret.Interpret t f => Data.HFunctor.Interpret.Interpret (Data.HFunctor.HLift t) f instance forall k (t :: (k -> *) -> k -> *) (f :: k -> *). Data.HFunctor.Interpret.Interpret t f => Data.HFunctor.Interpret.Interpret (Data.HFunctor.HFree t) f -- | This module provides an abstraction for "two-argument functor -- combinators", HBifunctor, as well as some useful combinators. module Data.HBifunctor -- | A HBifunctor is like an HFunctor, but it enhances -- two different functors instead of just one. -- -- Usually, it enhaces them "together" in some sort of combining way. -- -- This typeclass provides a uniform instance for "swapping out" or -- "hoisting" the enhanced functors. We can hoist the first one with -- hleft, the second one with hright, or both at the same -- time with hbimap. -- -- For example, the f :*: g type gives us "both f and -- g": -- --
-- data (f :*: g) a = f a :*: g a ---- -- It combines both f and g into a unified structure -- --- here, it does it by providing both f and g. -- -- The single law is: -- --
-- hbimap id id == id ---- -- This ensures that hleft, hright, and hbimap do -- not affect the structure that t adds on top of the underlying -- functors. class HBifunctor (t :: (k -> Type) -> (k -> Type) -> k -> Type) -- | Swap out the first transformed functor. hleft :: HBifunctor t => (f ~> j) -> t f g ~> t j g -- | Swap out the second transformed functor. hright :: HBifunctor t => (g ~> l) -> t f g ~> t f l -- | Swap out both transformed functors at the same time. hbimap :: HBifunctor t => (f ~> j) -> (g ~> l) -> t f g ~> t j l -- | Useful newtype to allow us to derive an HFunctor instance from -- any instance of HBifunctor, using -XDerivingVia. -- -- For example, because we have instance HBifunctor -- Day, we can write: -- --
-- deriving via (WrappedHBifunctor Day f) instance HFunctor (Day f) ---- -- to give us an automatic HFunctor instance and save us some -- work. newtype WrappedHBifunctor t (f :: k -> Type) (g :: k -> Type) (a :: k) WrapHBifunctor :: t f g a -> WrappedHBifunctor t (f :: k -> Type) (g :: k -> Type) (a :: k) [unwrapHBifunctor] :: WrappedHBifunctor t (f :: k -> Type) (g :: k -> Type) (a :: k) -> t f g a -- | Lift two isomorphisms on each side of a bifunctor to become an -- isomorphism between the two bifunctor applications. -- -- Basically, if f and f' are isomorphic, and -- g and g' are isomorphic, then t f g is -- isomorphic to t f' g'. overHBifunctor :: HBifunctor t => (f <~> f') -> (g <~> g') -> t f g <~> t f' g' -- | An HBifunctor that ignores its second input. Like a :+: -- with no R1/right branch. -- -- This is Joker from Data.Bifunctors.Joker, but given a -- more sensible name for its purpose. newtype LeftF f g a LeftF :: f a -> LeftF f g a [runLeftF] :: LeftF f g a -> f a -- | An HBifunctor that ignores its first input. Like a :+: -- with no L1/left branch. -- -- In its polykinded form (on f), it is essentially a -- higher-order version of Tagged. newtype RightF f g a RightF :: g a -> RightF f g a [runRightF] :: RightF f g a -> g a instance forall k (g :: k -> *). Data.HFunctor.Internal.HFunctor (Data.HBifunctor.RightF g) instance forall k (g :: * -> *) (f :: k). Data.Functor.Classes.Ord1 g => Data.Functor.Classes.Ord1 (Data.HBifunctor.RightF f g) instance Data.HFunctor.Internal.HBifunctor Data.HBifunctor.RightF instance forall k1 k2 (g :: k1). Data.HFunctor.Internal.HFunctor (Data.HBifunctor.RightF g) instance forall k1 k2 (g :: k1). Data.HFunctor.Inject (Data.HBifunctor.RightF g) instance forall k1 k2 (g :: k1). Data.HFunctor.HBind (Data.HBifunctor.RightF g) instance forall k1 k2 (g :: k1) (f :: k2 -> *). Data.HFunctor.Interpret.Interpret (Data.HBifunctor.RightF g) f instance forall k (g :: * -> *) (f :: k). Data.Functor.Classes.Eq1 g => Data.Functor.Classes.Eq1 (Data.HBifunctor.RightF f g) instance forall k (g :: * -> *) (f :: k). Data.Functor.Classes.Read1 g => Data.Functor.Classes.Read1 (Data.HBifunctor.RightF f g) instance forall k (g :: * -> *) (f :: k). Data.Functor.Classes.Show1 g => Data.Functor.Classes.Show1 (Data.HBifunctor.RightF f g) instance forall k1 (f :: k1) k2 (g :: k2 -> *) (a :: k2). (Data.Typeable.Internal.Typeable f, Data.Typeable.Internal.Typeable a, Data.Typeable.Internal.Typeable g, Data.Typeable.Internal.Typeable k1, Data.Typeable.Internal.Typeable k2, Data.Data.Data (g a)) => Data.Data.Data (Data.HBifunctor.RightF f g a) instance forall k1 (f :: k1) k2 (g :: k2 -> *) (a :: k2). GHC.Generics.Generic (Data.HBifunctor.RightF f g a) instance forall k (f :: k) (g :: * -> *). Data.Traversable.Traversable g => Data.Traversable.Traversable (Data.HBifunctor.RightF f g) instance forall k (f :: k) (g :: * -> *). Data.Foldable.Foldable g => Data.Foldable.Foldable (Data.HBifunctor.RightF f g) instance forall k (f :: k) (g :: * -> *). GHC.Base.Functor g => GHC.Base.Functor (Data.HBifunctor.RightF f g) instance forall k1 (f :: k1) k2 (g :: k2 -> *) (a :: k2). GHC.Classes.Ord (g a) => GHC.Classes.Ord (Data.HBifunctor.RightF f g a) instance forall k1 (f :: k1) k2 (g :: k2 -> *) (a :: k2). GHC.Classes.Eq (g a) => GHC.Classes.Eq (Data.HBifunctor.RightF f g a) instance forall k1 (f :: k1) k2 (g :: k2 -> *) (a :: k2). GHC.Read.Read (g a) => GHC.Read.Read (Data.HBifunctor.RightF f g a) instance forall k1 (f :: k1) k2 (g :: k2 -> *) (a :: k2). GHC.Show.Show (g a) => GHC.Show.Show (Data.HBifunctor.RightF f g a) instance forall k (f :: k -> *). Data.HFunctor.Internal.HFunctor (Data.HBifunctor.LeftF f) instance Data.Traversable.Traversable f => Data.Bitraversable.Bitraversable (Data.HBifunctor.LeftF f) instance GHC.Base.Applicative f => Data.Biapplicative.Biapplicative (Data.HBifunctor.LeftF f) instance Data.HFunctor.Internal.HBifunctor Data.HBifunctor.LeftF instance Data.Foldable.Foldable f => Data.Bifoldable.Bifoldable (Data.HBifunctor.LeftF f) instance GHC.Base.Functor f => Data.Bifunctor.Bifunctor (Data.HBifunctor.LeftF f) instance forall k (f :: * -> *) (g :: k). Data.Functor.Classes.Ord1 f => Data.Functor.Classes.Ord1 (Data.HBifunctor.LeftF f g) instance forall k (f :: * -> *) (g :: k). Data.Functor.Classes.Eq1 f => Data.Functor.Classes.Eq1 (Data.HBifunctor.LeftF f g) instance forall k (f :: * -> *) (g :: k). Data.Functor.Classes.Read1 f => Data.Functor.Classes.Read1 (Data.HBifunctor.LeftF f g) instance forall k (f :: * -> *) (g :: k). Data.Functor.Classes.Show1 f => Data.Functor.Classes.Show1 (Data.HBifunctor.LeftF f g) instance forall k1 (f :: k1 -> *) k2 (g :: k2) (a :: k1). (Data.Typeable.Internal.Typeable g, Data.Typeable.Internal.Typeable a, Data.Typeable.Internal.Typeable f, Data.Typeable.Internal.Typeable k1, Data.Typeable.Internal.Typeable k2, Data.Data.Data (f a)) => Data.Data.Data (Data.HBifunctor.LeftF f g a) instance forall k1 (f :: k1 -> *) k2 (g :: k2) (a :: k1). GHC.Generics.Generic (Data.HBifunctor.LeftF f g a) instance forall (f :: * -> *) k (g :: k). Data.Traversable.Traversable f => Data.Traversable.Traversable (Data.HBifunctor.LeftF f g) instance forall (f :: * -> *) k (g :: k). Data.Foldable.Foldable f => Data.Foldable.Foldable (Data.HBifunctor.LeftF f g) instance forall (f :: * -> *) k (g :: k). GHC.Base.Functor f => GHC.Base.Functor (Data.HBifunctor.LeftF f g) instance forall k1 (f :: k1 -> *) k2 (g :: k2) (a :: k1). GHC.Classes.Ord (f a) => GHC.Classes.Ord (Data.HBifunctor.LeftF f g a) instance forall k1 (f :: k1 -> *) k2 (g :: k2) (a :: k1). GHC.Classes.Eq (f a) => GHC.Classes.Eq (Data.HBifunctor.LeftF f g a) instance forall k1 (f :: k1 -> *) k2 (g :: k2) (a :: k1). GHC.Read.Read (f a) => GHC.Read.Read (Data.HBifunctor.LeftF f g a) instance forall k1 (f :: k1 -> *) k2 (g :: k2) (a :: k1). GHC.Show.Show (f a) => GHC.Show.Show (Data.HBifunctor.LeftF f g a) -- | Provides free structures for the various typeclasses of the -- Divisible hierarchy. module Data.Functor.Contravariant.Divisible.Free -- | The free Divisible. Used to sequence multiple contravariant -- consumers, splitting out the input across all consumers. -- -- Note that Div f is essentially ListF -- (Coyoneda f), or just ListF f in the case -- that f is already contravariant. However, this is left in -- here because it can be more convenient to use if you are working with -- an intermediate f that isn't Contravariant. data Div :: (Type -> Type) -> Type -> Type [Conquer] :: Div f a [Divide] :: (a -> (b, c)) -> f b -> Div f c -> Div f a -- | Map over the undering context in a Div. hoistDiv :: forall f g. (f ~> g) -> Div f ~> Div g -- | Inject a single action in f into a Div f. liftDiv :: f ~> Div f -- | Interpret a Div into a context g, provided g -- is Divisible. runDiv :: forall f g. Divisible g => (f ~> g) -> Div f ~> g -- | Div is isomorphic to ListF for contravariant f. -- This witnesses one way of that isomorphism. -- -- Be aware that this is essentially O(n^2). divListF :: forall f. Contravariant f => Div f ~> ListF f -- | Div is isomorphic to ListF for contravariant f. -- This witnesses one way of that isomorphism. -- -- This direction is O(n), unlike divListF. listFDiv :: ListF f ~> Div f -- | The free Divise: a non-empty version of Div. -- -- Note that Div1 f is essentially NonEmptyF -- (Coyoneda f), or just NonEmptyF f in the -- case that f is already contravariant. However, it can be more -- convenient to use if you are working with an intermediate f -- that isn't Contravariant. data Div1 :: (Type -> Type) -> Type -> Type [Div1] :: (a -> (b, c)) -> f b -> Div f c -> Div1 f a -- | Map over the undering context in a Div1. hoistDiv1 :: (f ~> g) -> Div1 f ~> Div1 g -- | Inject a single action in f into a Div f. liftDiv1 :: f ~> Div1 f -- | A Div1 is a "non-empty" Div; this function "forgets" the -- non-empty property and turns it back into a normal Div. toDiv :: Div1 f a -> Div f a -- | Interpret a Div1 into a context g, provided g -- is Divise. runDiv1 :: Divise g => (f ~> g) -> Div1 f ~> g -- | Div1 is isomorphic to NonEmptyF for contravariant -- f. This witnesses one way of that isomorphism. -- -- Be aware that this is essentially O(n^2). div1NonEmptyF :: Contravariant f => Div1 f ~> NonEmptyF f -- | Div1 is isomorphic to NonEmptyF for contravariant -- f. This witnesses one way of that isomorphism. -- -- This direction is O(n), unlike div1NonEmptyF. nonEmptyFDiv1 :: NonEmptyF f ~> Div1 f -- | The free Decide. Used to aggregate multiple possible consumers, -- directing the input into an appropriate consumer. data Dec :: (Type -> Type) -> Type -> Type [Lose] :: (a -> Void) -> Dec f a [Choose] :: (a -> Either b c) -> f b -> Dec f c -> Dec f a -- | Map over the undering context in a Dec. hoistDec :: forall f g. (f ~> g) -> Dec f ~> Dec g -- | Inject a single action in f into a Dec f. liftDec :: f ~> Dec f -- | Interpret a Dec into a context g, provided g -- is Conclude. runDec :: forall f g. Conclude g => (f ~> g) -> Dec f ~> g -- | The free Decide: a non-empty version of Dec. data Dec1 :: (Type -> Type) -> Type -> Type [Dec1] :: (a -> Either b c) -> f b -> Dec f c -> Dec1 f a -- | Map over the undering context in a Dec1. hoistDec1 :: forall f g. (f ~> g) -> Dec1 f ~> Dec1 g -- | Inject a single action in f into a Dec1 f. liftDec1 :: f ~> Dec1 f -- | A Dec1 is a "non-empty" Dec; this function "forgets" the -- non-empty property and turns it back into a normal Dec. toDec :: Dec1 f a -> Dec f a -- | Interpret a Dec1 into a context g, provided g -- is Decide. runDec1 :: Decide g => (f ~> g) -> Dec1 f ~> g instance Data.Functor.Contravariant.Contravariant (Data.Functor.Contravariant.Divisible.Free.Dec1 f) instance Data.Functor.Invariant.Invariant (Data.Functor.Contravariant.Divisible.Free.Dec1 f) instance Data.Functor.Contravariant.Decide.Decide (Data.Functor.Contravariant.Divisible.Free.Dec1 f) instance Data.HFunctor.Internal.HFunctor Data.Functor.Contravariant.Divisible.Free.Dec1 instance Data.HFunctor.Inject Data.Functor.Contravariant.Divisible.Free.Dec1 instance Data.Functor.Contravariant.Decide.Decide f => Data.HFunctor.Interpret.Interpret Data.Functor.Contravariant.Divisible.Free.Dec1 f instance Data.Functor.Contravariant.Contravariant (Data.Functor.Contravariant.Divisible.Free.Dec f) instance Data.Functor.Invariant.Invariant (Data.Functor.Contravariant.Divisible.Free.Dec f) instance Data.Functor.Contravariant.Decide.Decide (Data.Functor.Contravariant.Divisible.Free.Dec f) instance Data.Functor.Contravariant.Conclude.Conclude (Data.Functor.Contravariant.Divisible.Free.Dec f) instance Data.HFunctor.Internal.HFunctor Data.Functor.Contravariant.Divisible.Free.Dec instance Data.HFunctor.Inject Data.Functor.Contravariant.Divisible.Free.Dec instance Data.Functor.Contravariant.Conclude.Conclude f => Data.HFunctor.Interpret.Interpret Data.Functor.Contravariant.Divisible.Free.Dec f instance Data.Functor.Contravariant.Contravariant (Data.Functor.Contravariant.Divisible.Free.Div1 f) instance Data.Functor.Invariant.Invariant (Data.Functor.Contravariant.Divisible.Free.Div1 f) instance Data.Functor.Contravariant.Divise.Divise (Data.Functor.Contravariant.Divisible.Free.Div1 f) instance Data.HFunctor.Internal.HFunctor Data.Functor.Contravariant.Divisible.Free.Div1 instance Data.HFunctor.Inject Data.Functor.Contravariant.Divisible.Free.Div1 instance Data.Functor.Contravariant.Divise.Divise f => Data.HFunctor.Interpret.Interpret Data.Functor.Contravariant.Divisible.Free.Div1 f instance Data.Functor.Contravariant.Contravariant (Data.Functor.Contravariant.Divisible.Free.Div f) instance Data.Functor.Invariant.Invariant (Data.Functor.Contravariant.Divisible.Free.Div f) instance Data.Functor.Contravariant.Divise.Divise (Data.Functor.Contravariant.Divisible.Free.Div f) instance Data.Functor.Contravariant.Divisible.Divisible (Data.Functor.Contravariant.Divisible.Free.Div f) instance Data.HFunctor.Internal.HFunctor Data.Functor.Contravariant.Divisible.Free.Div instance Data.HFunctor.Inject Data.Functor.Contravariant.Divisible.Free.Div instance Data.Functor.Contravariant.Divisible.Divisible f => Data.HFunctor.Interpret.Interpret Data.Functor.Contravariant.Divisible.Free.Div f -- | The free Apply. Provides Ap1 and various utility -- methods. See Ap1 for more details. -- -- Ideally Ap1 would be in the free package. However, it is -- defined here for now. module Data.Functor.Apply.Free -- | One or more fs convolved with itself. -- -- Essentially: -- --
-- Ap1 f -- ~ f -- one f -- :+: (f `Day` f) -- two f's -- :+: (f `Day` f `Day` f) -- three f's -- :+: (f `Day` f `Day` f `Day` f) -- four f's -- :+: ... -- etc. ---- -- Useful if you want to promote an f to a situation with "at -- least one f sequenced with itself". -- -- Mostly useful for its HFunctor and Interpret instance, -- along with its relationship with Ap and Day. -- -- This is the free Apply --- Basically a "non-empty" Ap. -- -- The construction here is based on Ap, similar to now -- NonEmpty is built on list. data Ap1 :: (Type -> Type) -> Type -> Type [Ap1] :: f a -> Ap f (a -> b) -> Ap1 f b -- | An Ap1 f is just a Day f (Ap -- f). This bidirectional pattern synonym lets you treat it as such. pattern DayAp1 :: Day f (Ap f) a -> Ap1 f a -- | An Ap1 is a "non-empty" Ap; this function "forgets" the -- non-empty property and turns it back into a normal Ap. toAp :: Ap1 f ~> Ap f -- | Convert an Ap into an Ap1 if possible. If the Ap -- was "empty", return the Pure value instead. fromAp :: Ap f ~> (Identity :+: Ap1 f) -- | Embed an f into Ap1. liftAp1 :: f ~> Ap1 f -- | Extract the f out of the Ap1. -- --
-- retractAp1 . liftAp1 == id --retractAp1 :: Apply f => Ap1 f ~> f -- | Interpret an Ap f into some Apply context -- g. runAp1 :: Apply g => (f ~> g) -> Ap1 f ~> g instance GHC.Base.Functor (Data.Functor.Apply.Free.Ap1 f) instance Data.Functor.Invariant.Invariant (Data.Functor.Apply.Free.Ap1 f) instance Data.Functor.Bind.Class.Apply (Data.Functor.Apply.Free.Ap1 f) instance Data.HFunctor.Internal.HFunctor Data.Functor.Apply.Free.Ap1 instance Data.HFunctor.Inject Data.Functor.Apply.Free.Ap1 instance Data.HFunctor.HBind Data.Functor.Apply.Free.Ap1 instance Data.Functor.Bind.Class.Apply f => Data.HFunctor.Interpret.Interpret Data.Functor.Apply.Free.Ap1 f -- | Provides Final, which can be considered the "free -- Interpret over a constraint": generate a handy Interpret -- instance for any constraint c. module Data.HFunctor.Final -- | A simple way to inject/reject into any eventual typeclass. -- -- In a way, this is the "ultimate" multi-purpose Interpret -- instance. You can use this to inject an f into a free -- structure of any typeclass. If you want f to have a -- Monad instance, for example, just use -- --
-- inject :: f a -> Final Monad f a ---- -- When you want to eventually interpret out the data, use: -- --
-- interpret :: (f ~> g) -> Final c f a -> g a ---- -- Essentially, Final c is the "free c". Final -- Monad is the free Monad, etc. -- -- Final can theoretically replace Ap, Ap1, -- ListF, NonEmptyF, MaybeF, Free, -- Identity, Coyoneda, and other instances of -- FreeOf, if you don't care about being able to pattern match on -- explicit structure. -- -- However, it cannot replace Interpret instances that are not -- free structures, like Step, Steps, Backwards, -- etc. -- -- Note that this doesn't have instances for all the typeclasses -- you could lift things into; you probably have to define your own if -- you want to use Final c as an instance of -- c (using liftFinal0, liftFinal1, -- liftFinal2 for help). newtype Final c f a Final :: (forall g. c g => (forall x. f x -> g x) -> g a) -> Final c f a [runFinal] :: Final c f a -> forall g. c g => (forall x. f x -> g x) -> g a -- | Concretize a Final. -- --
-- fromFinal :: Final Functor f ~> Coyoneda f -- fromFinal :: Final Applicative f ~> Ap f -- fromFinal :: Final Alternative f ~> Alt f -- fromFinal :: Final Monad f ~> Free f -- fromFinal :: Final Pointed f ~> Lift f -- fromFinal :: Final Plus f ~> ListF f ---- -- This can be useful because Final doesn't have a concrete -- structure that you can pattern match on and inspect, but t -- might. -- -- In the case that this forms an isomorphism with toFinal, the -- t will have an instance of FreeOf. fromFinal :: (Inject t, c (t f)) => Final c f ~> t f -- | Finalize an Interpret instance. -- --
-- toFinal :: Coyoneda f ~> Final Functor f -- toFinal :: Ap f ~> Final Applicative f -- toFinal :: Alt f ~> Final Alternative f -- toFinal :: Free f ~> Final Monad f -- toFinal :: Lift f ~> Final Pointed f -- toFinal :: ListF f ~> Final Plus f ---- -- Note that the instance of c for Final c must -- be defined. -- -- This operation can potentially forget structure in t. -- For example, we have: -- --
-- toFinal :: Steps f ~> Final Alt f ---- -- In this process, we lose the "positional" structure of Steps. -- -- In the case where toFinal doesn't lose any information, this -- will form an isomorphism with fromFinal, and t is -- known as the "Free c". For such a situation, t will -- have a FreeOf instance. toFinal :: Interpret t (Final c f) => t f ~> Final c f -- | A typeclass associating a free structure with the typeclass it is free -- on. -- -- This essentially lists instances of Interpret where a "trip" -- through Final will leave it unchanged. -- --
-- fromFree . toFree == id -- toFree . fromFree == id ---- -- This can be useful because Final doesn't have a concrete -- structure that you can pattern match on and inspect, but t -- might. This lets you work on a concrete structure if you desire. class FreeOf c t | t -> c where { -- | What "type" of functor is expected: should be either -- Unconstrained, Functor, Contravariant, or -- Invariant. type family FreeFunctorBy t :: (Type -> Type) -> Constraint; type FreeFunctorBy t = Unconstrained; } fromFree :: FreeOf c t => t f ~> Final c f toFree :: (FreeOf c t, FreeFunctorBy t f) => Final c f ~> t f fromFree :: (FreeOf c t, Interpret t (Final c f)) => t f ~> Final c f toFree :: (FreeOf c t, Inject t, c (t f)) => Final c f ~> t f -- | The isomorphism between a free structure and its encoding as -- Final. finalizing :: (FreeOf c t, FreeFunctorBy t f) => t f <~> Final c f -- | Re-interpret the context under a Final. hoistFinalC :: (forall g x. (c g => g x) -> d g => g x) -> Final c f a -> Final d f a -- | Lift an action into a Final. liftFinal0 :: (forall g. c g => g a) -> Final c f a -- | Map the action in a Final. liftFinal1 :: (forall g. c g => g a -> g b) -> Final c f a -> Final c f b -- | Merge two Final actions. liftFinal2 :: (forall g. c g => g a -> g b -> g d) -> Final c f a -> Final c f b -> Final c f d instance Data.HFunctor.Final.FreeOf GHC.Base.Functor Data.Functor.Coyoneda.Coyoneda instance Data.HFunctor.Final.FreeOf Data.Functor.Contravariant.Contravariant Data.Functor.Contravariant.Coyoneda.Coyoneda instance Data.HFunctor.Final.FreeOf GHC.Base.Applicative Control.Applicative.Free.Ap instance Data.HFunctor.Final.FreeOf Data.Functor.Bind.Class.Apply Data.Functor.Apply.Free.Ap1 instance Data.HFunctor.Final.FreeOf GHC.Base.Applicative Control.Applicative.Free.Fast.Ap instance Data.HFunctor.Final.FreeOf GHC.Base.Alternative Control.Alternative.Free.Alt instance Data.HFunctor.Final.FreeOf GHC.Base.Monad Control.Monad.Freer.Church.Free instance Data.HFunctor.Final.FreeOf Data.Functor.Bind.Class.Bind Control.Monad.Freer.Church.Free1 instance Data.HFunctor.Final.FreeOf Data.Pointed.Pointed Control.Applicative.Lift.Lift instance Data.HFunctor.Final.FreeOf Data.Pointed.Pointed Data.Functor.Bind.Class.MaybeApply instance Data.HFunctor.Final.FreeOf Data.Functor.Alt.Alt Control.Applicative.ListF.NonEmptyF instance Data.HFunctor.Final.FreeOf Data.Functor.Plus.Plus Control.Applicative.ListF.ListF instance Data.HFunctor.Final.FreeOf Data.Functor.Contravariant.Divise.Divise Data.Functor.Contravariant.Divisible.Free.Div1 instance Data.HFunctor.Final.FreeOf Data.Functor.Contravariant.Divisible.Divisible Data.Functor.Contravariant.Divisible.Free.Div instance Data.HFunctor.Final.FreeOf Data.Functor.Contravariant.Decide.Decide Data.Functor.Contravariant.Divisible.Free.Dec1 instance Data.HFunctor.Final.FreeOf Data.Functor.Contravariant.Conclude.Conclude Data.Functor.Contravariant.Divisible.Free.Dec instance Data.HFunctor.Final.FreeOf Data.Constraint.Trivial.Unconstrained Control.Monad.Trans.Identity.IdentityT instance GHC.Base.Functor (Data.HFunctor.Final.Final GHC.Base.Functor f) instance GHC.Base.Functor (Data.HFunctor.Final.Final Data.Functor.Bind.Class.Apply f) instance Data.Functor.Bind.Class.Apply (Data.HFunctor.Final.Final Data.Functor.Bind.Class.Apply f) instance GHC.Base.Functor (Data.HFunctor.Final.Final Data.Functor.Bind.Class.Bind f) instance Data.Functor.Bind.Class.Apply (Data.HFunctor.Final.Final Data.Functor.Bind.Class.Bind f) instance Data.Functor.Bind.Class.Bind (Data.HFunctor.Final.Final Data.Functor.Bind.Class.Bind f) instance GHC.Base.Functor (Data.HFunctor.Final.Final GHC.Base.Applicative f) instance Data.Functor.Bind.Class.Apply (Data.HFunctor.Final.Final GHC.Base.Applicative f) instance GHC.Base.Applicative (Data.HFunctor.Final.Final GHC.Base.Applicative f) instance GHC.Base.Functor (Data.HFunctor.Final.Final GHC.Base.Alternative f) instance Data.Functor.Bind.Class.Apply (Data.HFunctor.Final.Final GHC.Base.Alternative f) instance GHC.Base.Applicative (Data.HFunctor.Final.Final GHC.Base.Alternative f) instance Data.Functor.Alt.Alt (Data.HFunctor.Final.Final GHC.Base.Alternative f) instance Data.Functor.Plus.Plus (Data.HFunctor.Final.Final GHC.Base.Alternative f) instance GHC.Base.Alternative (Data.HFunctor.Final.Final GHC.Base.Alternative f) instance GHC.Base.Functor (Data.HFunctor.Final.Final GHC.Base.Monad f) instance Data.Functor.Bind.Class.Apply (Data.HFunctor.Final.Final GHC.Base.Monad f) instance GHC.Base.Applicative (Data.HFunctor.Final.Final GHC.Base.Monad f) instance GHC.Base.Monad (Data.HFunctor.Final.Final GHC.Base.Monad f) instance GHC.Base.Functor (Data.HFunctor.Final.Final GHC.Base.MonadPlus f) instance GHC.Base.Applicative (Data.HFunctor.Final.Final GHC.Base.MonadPlus f) instance GHC.Base.Monad (Data.HFunctor.Final.Final GHC.Base.MonadPlus f) instance Data.Functor.Alt.Alt (Data.HFunctor.Final.Final GHC.Base.MonadPlus f) instance Data.Functor.Plus.Plus (Data.HFunctor.Final.Final GHC.Base.MonadPlus f) instance GHC.Base.Alternative (Data.HFunctor.Final.Final GHC.Base.MonadPlus f) instance GHC.Base.MonadPlus (Data.HFunctor.Final.Final GHC.Base.MonadPlus f) instance Data.Pointed.Pointed (Data.HFunctor.Final.Final Data.Pointed.Pointed f) instance GHC.Base.Functor (Data.HFunctor.Final.Final (Control.Monad.Reader.Class.MonadReader r) f) instance GHC.Base.Applicative (Data.HFunctor.Final.Final (Control.Monad.Reader.Class.MonadReader r) f) instance Data.Functor.Bind.Class.Apply (Data.HFunctor.Final.Final (Control.Monad.Reader.Class.MonadReader r) f) instance GHC.Base.Monad (Data.HFunctor.Final.Final (Control.Monad.Reader.Class.MonadReader r) f) instance Control.Monad.Reader.Class.MonadReader r (Data.HFunctor.Final.Final (Control.Monad.Reader.Class.MonadReader r) f) instance GHC.Base.Functor (Data.HFunctor.Final.Final Data.Functor.Alt.Alt f) instance Data.Functor.Alt.Alt (Data.HFunctor.Final.Final Data.Functor.Alt.Alt f) instance GHC.Base.Functor (Data.HFunctor.Final.Final Data.Functor.Plus.Plus f) instance Data.Functor.Alt.Alt (Data.HFunctor.Final.Final Data.Functor.Plus.Plus f) instance Data.Functor.Plus.Plus (Data.HFunctor.Final.Final Data.Functor.Plus.Plus f) instance Data.Functor.Contravariant.Contravariant (Data.HFunctor.Final.Final Data.Functor.Contravariant.Contravariant f) instance Data.Functor.Contravariant.Contravariant (Data.HFunctor.Final.Final Data.Functor.Contravariant.Divise.Divise f) instance Data.Functor.Contravariant.Divise.Divise (Data.HFunctor.Final.Final Data.Functor.Contravariant.Divise.Divise f) instance Data.Functor.Contravariant.Contravariant (Data.HFunctor.Final.Final Data.Functor.Contravariant.Divisible.Divisible f) instance Data.Functor.Contravariant.Divise.Divise (Data.HFunctor.Final.Final Data.Functor.Contravariant.Divisible.Divisible f) instance Data.Functor.Contravariant.Divisible.Divisible (Data.HFunctor.Final.Final Data.Functor.Contravariant.Divisible.Divisible f) instance Data.Functor.Contravariant.Contravariant (Data.HFunctor.Final.Final Data.Functor.Contravariant.Decide.Decide f) instance Data.Functor.Contravariant.Decide.Decide (Data.HFunctor.Final.Final Data.Functor.Contravariant.Decide.Decide f) instance Data.Functor.Contravariant.Contravariant (Data.HFunctor.Final.Final Data.Functor.Contravariant.Conclude.Conclude f) instance Data.Functor.Contravariant.Decide.Decide (Data.HFunctor.Final.Final Data.Functor.Contravariant.Conclude.Conclude f) instance Data.Functor.Contravariant.Conclude.Conclude (Data.HFunctor.Final.Final Data.Functor.Contravariant.Conclude.Conclude f) instance Data.Functor.Contravariant.Contravariant (Data.HFunctor.Final.Final Data.Functor.Contravariant.Divisible.Decidable f) instance Data.Functor.Contravariant.Divisible.Divisible (Data.HFunctor.Final.Final Data.Functor.Contravariant.Divisible.Decidable f) instance Data.Functor.Contravariant.Decide.Decide (Data.HFunctor.Final.Final Data.Functor.Contravariant.Divisible.Decidable f) instance Data.Functor.Contravariant.Conclude.Conclude (Data.HFunctor.Final.Final Data.Functor.Contravariant.Divisible.Decidable f) instance Data.Functor.Contravariant.Divisible.Decidable (Data.HFunctor.Final.Final Data.Functor.Contravariant.Divisible.Decidable f) instance Data.Functor.Invariant.Invariant (Data.HFunctor.Final.Final Data.Functor.Invariant.Invariant f) instance forall k (c :: (k -> *) -> GHC.Types.Constraint). Data.HFunctor.Internal.HFunctor (Data.HFunctor.Final.Final c) instance forall k (c :: (k -> *) -> GHC.Types.Constraint). Data.HFunctor.Inject (Data.HFunctor.Final.Final c) instance forall k (c :: (k -> *) -> GHC.Types.Constraint) (f :: k -> *). c f => Data.HFunctor.Interpret.Interpret (Data.HFunctor.Final.Final c) f -- | This module provides tools for working with binary functor combinators -- that represent interpretable schemas. -- -- These are types HBifunctor t that take two functors -- f and g and returns a new functor t f g, -- that "mixes together" f and g in some way. -- -- The high-level usage of this is -- --
-- biretract :: SemigroupIn t f => t f f ~> f ---- -- which lets you fully "mix" together the two input functors. -- --
-- biretract :: (f :+: f) a -> f a -- biretract :: Plus f => (f :*: f) a -> f a -- biretract :: Applicative f => Day f f a -> f a -- biretract :: Monad f => Comp f f a -> f a ---- -- See Data.HBifunctor.Tensor for the next stage of structure in -- tensors and moving in and out of them. module Data.HBifunctor.Associative -- | An HBifunctor where it doesn't matter which binds first is -- Associative. Knowing this gives us a lot of power to rearrange -- the internals of our HFunctor at will. -- -- For example, for the functor product: -- --
-- data (f :*: g) a = f a :*: g a ---- -- We know that f :*: (g :*: h) is the same as (f :*: g) :*: -- h. -- -- Formally, we can say that t enriches a the category of -- endofunctors with semigroup strcture: it turns our endofunctor -- category into a "semigroupoidal category". -- -- Different instances of t each enrich the endofunctor category -- in different ways, giving a different semigroupoidal category. class (HBifunctor t, Inject (NonEmptyBy t)) => Associative t where { -- | The "semigroup functor combinator" generated by t. -- -- A value of type NonEmptyBy t f a is equivalent to one -- of: -- --
f a
t f f a
t f (t f f) a
t f (t f (t f f)) a
t f (t f (t f (t f f))) a
-- x ~ NonEmptyF (x :| []) ~ inject x
-- x :*: y ~ NonEmptyF (x :| [y]) ~ toNonEmptyBy (x :*: y)
-- x :*: y :*: z ~ NonEmptyF (x :| [y,z])
-- -- etc.
--
--
-- You can create an "singleton" one with inject, or else one from
-- a single t f f with toNonEmptyBy.
--
-- See ListBy for a "possibly empty" version of this type.
type family NonEmptyBy t :: (Type -> Type) -> Type -> Type;
-- | A description of "what type of Functor" this tensor is expected to be
-- applied to. This should typically always be either Functor,
-- Contravariant, or Invariant.
type family FunctorBy t :: (Type -> Type) -> Constraint;
type FunctorBy t = Unconstrained;
}
-- | The isomorphism between t f (t g h) a and t (t f g) h
-- a. To use this isomorphism, see assoc and disassoc.
associating :: (Associative t, FunctorBy t f, FunctorBy t g, FunctorBy t h) => t f (t g h) <~> t (t f g) h
-- | If a NonEmptyBy t f represents multiple applications
-- of t f to itself, then we can also "append" two
-- NonEmptyBy t fs applied to themselves into one giant
-- NonEmptyBy t f containing all of the t fs.
--
-- Note that this essentially gives an instance for
-- SemigroupIn t (NonEmptyBy t f), for any functor
-- f.
appendNE :: Associative t => t (NonEmptyBy t f) (NonEmptyBy t f) ~> NonEmptyBy t f
-- | If a NonEmptyBy t f represents multiple applications
-- of t f to itself, then we can split it based on whether or
-- not it is just a single f or at least one top-level
-- application of t f.
--
-- Note that you can recursively "unroll" a NonEmptyBy completely
-- into a Chain1 by using unrollNE.
matchNE :: (Associative t, FunctorBy t f) => NonEmptyBy t f ~> (f :+: t f (NonEmptyBy t f))
-- | Prepend an application of t f to the front of a
-- NonEmptyBy t f.
consNE :: Associative t => t f (NonEmptyBy t f) ~> NonEmptyBy t f
-- | Embed a direct application of f to itself into a
-- NonEmptyBy t f.
toNonEmptyBy :: Associative t => t f f ~> NonEmptyBy t f
-- | Reassociate an application of t.
assoc :: (Associative t, FunctorBy t f, FunctorBy t g, FunctorBy t h) => t f (t g h) ~> t (t f g) h
-- | Reassociate an application of t.
disassoc :: (Associative t, FunctorBy t f, FunctorBy t g, FunctorBy t h) => t (t f g) h ~> t f (t g h)
-- | For different Associative t, we have functors
-- f that we can "squash", using biretract:
--
-- -- t f f ~> f ---- -- This gives us the ability to squash applications of t. -- -- Formally, if we have Associative t, we are enriching -- the category of endofunctors with semigroup structure, turning it into -- a semigroupoidal category. Different choices of t give -- different semigroupoidal categories. -- -- A functor f is known as a "semigroup in the (semigroupoidal) -- category of endofunctors on t" if we can biretract: -- --
-- t f f ~> f ---- -- This gives us a few interesting results in category theory, which you -- can stil reading about if you don't care: -- --
-- instance Bind f => SemigroupIn Comp f ---- -- Any other sort of instance and it's easy to run into problems with -- type inference. If you want to write an instance that's "polymorphic" -- on tensor choice, use the WrapHBF newtype wrapper over a type -- variable, where the second argument also uses a type constructor: -- --
-- instance SemigroupIn (WrapHBF t) (MyFunctor t i) ---- -- This will prevent problems with overloaded instances. class (Associative t, FunctorBy t f) => SemigroupIn t f -- | The HBifunctor analogy of retract. It retracts -- both fs into a single f, effectively fully -- mixing them together. -- -- This function makes f a semigroup in the category of -- endofunctors with respect to tensor t. biretract :: SemigroupIn t f => t f f ~> f -- | The HBifunctor analogy of retract. It retracts -- both fs into a single f, effectively fully -- mixing them together. -- -- This function makes f a semigroup in the category of -- endofunctors with respect to tensor t. biretract :: (SemigroupIn t f, Interpret (NonEmptyBy t) f) => t f f ~> f -- | The HBifunctor analogy of interpret. It takes two -- interpreting functions, and mixes them together into a target functor -- h. -- -- Note that this is useful in the poly-kinded case, but it is not -- possible to define generically for all SemigroupIn because it -- only is defined for Type -> Type inputes. See !+! -- for a version that is poly-kinded for :+: in specific. binterpret :: SemigroupIn t f => (g ~> f) -> (h ~> f) -> t g h ~> f -- | The HBifunctor analogy of interpret. It takes two -- interpreting functions, and mixes them together into a target functor -- h. -- -- Note that this is useful in the poly-kinded case, but it is not -- possible to define generically for all SemigroupIn because it -- only is defined for Type -> Type inputes. See !+! -- for a version that is poly-kinded for :+: in specific. binterpret :: (SemigroupIn t f, Interpret (NonEmptyBy t) f) => (g ~> f) -> (h ~> f) -> t g h ~> f -- | An NonEmptyBy t f represents the successive -- application of t to f, over and over again. So, that -- means that an NonEmptyBy t f must either be a single -- f, or an t f (NonEmptyBy t f). -- -- matchingNE states that these two are isomorphic. Use -- matchNE and inject !*! consNE to -- convert between one and the other. matchingNE :: (Associative t, FunctorBy t f) => NonEmptyBy t f <~> (f :+: t f (NonEmptyBy t f)) -- | An implementation of retract that works for any instance of -- SemigroupIn t for NonEmptyBy t. -- -- Can be useful as a default implementation if you already have -- SemigroupIn implemented. retractNE :: forall t f. SemigroupIn t f => NonEmptyBy t f ~> f -- | An implementation of interpret that works for any instance of -- SemigroupIn t for NonEmptyBy t. -- -- Can be useful as a default implementation if you already have -- SemigroupIn implemented. interpretNE :: forall t g f. SemigroupIn t f => (g ~> f) -> NonEmptyBy t g ~> f -- | Useful wrapper over binterpret to allow you to directly extract -- a value b out of the t f a, if you can convert f -- x into b. -- -- Note that depending on the constraints on f in -- SemigroupIn t f, you may have extra constraints on -- b. -- --
-- -- Return the length of either the list, or the Map, depending on which -- -- one s in the + -- biget length length -- :: ([] :+: Map Int) Char -- -> Int -- -- -- Return the length of both the list and the map, added together -- biget (Sum . length) (Sum . length) -- :: Day [] (Map Int) Char -- -> Sum Int --biget :: SemigroupIn t (Const b) => (forall x. f x -> b) -> (forall x. g x -> b) -> t f g a -> b -- | Useful wrapper over biget to allow you to collect a b -- from all instances of f and g inside a t f g -- a. -- -- This will work if the constraint on f for -- SemigroupIn t f is Apply or Applicative, -- or if it is unconstrained. bicollect :: SemigroupIn t (Const [b]) => (forall x. f x -> b) -> (forall x. g x -> b) -> t f g a -> [b] -- | Infix alias for binterpret -- -- Note that this is useful in the poly-kinded case, but it is not -- possible to define generically for all SemigroupIn because it -- only is defined for Type -> Type inputes. See !+! -- for a version that is poly-kinded for :+: in specific. (!*!) :: SemigroupIn t h => (f ~> h) -> (g ~> h) -> t f g ~> h infixr 5 !*! -- | Infix alias for biget -- --
-- -- Return the length of either the list, or the Map, depending on which -- -- one s in the + -- length !$! length -- :: ([] :+: Map Int) Char -- -> Int -- -- -- Return the length of both the list and the map, added together -- Sum . length !$! Sum . length -- :: Day [] (Map Int) Char -- -> Sum Int --(!$!) :: SemigroupIn t (Const b) => (forall x. f x -> b) -> (forall x. g x -> b) -> t f g a -> b infixr 5 !$! -- | A version of !*! specifically for :+: that is -- poly-kinded (!+!) :: (f ~> h) -> (g ~> h) -> (f :+: g) ~> h infixr 5 !+! -- | A newtype wrapper meant to be used to define polymorphic -- SemigroupIn instances. See documentation for SemigroupIn -- for more information. -- -- Please do not ever define an instance of SemigroupIn "naked" on -- the second parameter: -- --
-- instance SemigroupIn (WrapHBF t) f ---- -- As that would globally ruin everything using WrapHBF. newtype WrapHBF t f g a WrapHBF :: t f g a -> WrapHBF t f g a [unwrapHBF] :: WrapHBF t f g a -> t f g a -- | Any NonEmptyBy t f is a SemigroupIn t -- if we have Associative t. This newtype wrapper -- witnesses that fact. We require a newtype wrapper to avoid overlapping -- instances. newtype WrapNE t f a WrapNE :: NonEmptyBy t f a -> WrapNE t f a [unwrapNE] :: WrapNE t f a -> NonEmptyBy t f a instance forall k1 k2 k3 (t :: k1 -> k2 -> k3 -> *) (f :: k1) (g :: k2) (a :: k3). (Data.Typeable.Internal.Typeable f, Data.Typeable.Internal.Typeable g, Data.Typeable.Internal.Typeable a, Data.Typeable.Internal.Typeable t, Data.Typeable.Internal.Typeable k1, Data.Typeable.Internal.Typeable k2, Data.Typeable.Internal.Typeable k3, Data.Data.Data (t f g a)) => Data.Data.Data (Data.HBifunctor.Associative.WrapHBF t f g a) instance forall k1 k2 k3 (t :: k1 -> k2 -> k3 -> *) (f :: k1) (g :: k2) (a :: k3). GHC.Generics.Generic (Data.HBifunctor.Associative.WrapHBF t f g a) instance forall k1 k2 (t :: k1 -> k2 -> * -> *) (f :: k1) (g :: k2). Data.Traversable.Traversable (t f g) => Data.Traversable.Traversable (Data.HBifunctor.Associative.WrapHBF t f g) instance forall k1 k2 (t :: k1 -> k2 -> * -> *) (f :: k1) (g :: k2). Data.Foldable.Foldable (t f g) => Data.Foldable.Foldable (Data.HBifunctor.Associative.WrapHBF t f g) instance forall k1 k2 (t :: k1 -> k2 -> * -> *) (f :: k1) (g :: k2). GHC.Base.Functor (t f g) => GHC.Base.Functor (Data.HBifunctor.Associative.WrapHBF t f g) instance forall k1 k2 k3 (t :: k1 -> k2 -> k3 -> *) (f :: k1) (g :: k2) (a :: k3). GHC.Classes.Ord (t f g a) => GHC.Classes.Ord (Data.HBifunctor.Associative.WrapHBF t f g a) instance forall k1 k2 k3 (t :: k1 -> k2 -> k3 -> *) (f :: k1) (g :: k2) (a :: k3). GHC.Classes.Eq (t f g a) => GHC.Classes.Eq (Data.HBifunctor.Associative.WrapHBF t f g a) instance forall k1 k2 k3 (t :: k1 -> k2 -> k3 -> *) (f :: k1) (g :: k2) (a :: k3). GHC.Read.Read (t f g a) => GHC.Read.Read (Data.HBifunctor.Associative.WrapHBF t f g a) instance forall k1 k2 k3 (t :: k1 -> k2 -> k3 -> *) (f :: k1) (g :: k2) (a :: k3). GHC.Show.Show (t f g a) => GHC.Show.Show (Data.HBifunctor.Associative.WrapHBF t f g a) instance forall k (t :: (k -> *) -> (k -> *) -> k -> *) (f :: k -> *). Data.HFunctor.Internal.HBifunctor t => Data.HFunctor.Internal.HFunctor (Data.HBifunctor.Associative.WrapHBF t f) instance GHC.Base.Functor (Data.HBifunctor.Associative.NonEmptyBy t f) => GHC.Base.Functor (Data.HBifunctor.Associative.WrapNE t f) instance Data.Functor.Contravariant.Contravariant (Data.HBifunctor.Associative.NonEmptyBy t f) => Data.Functor.Contravariant.Contravariant (Data.HBifunctor.Associative.WrapNE t f) instance Data.Functor.Invariant.Invariant (Data.HBifunctor.Associative.NonEmptyBy t f) => Data.Functor.Invariant.Invariant (Data.HBifunctor.Associative.WrapNE t f) instance (Data.HBifunctor.Associative.Associative t, Data.HBifunctor.Associative.FunctorBy t f, Data.HBifunctor.Associative.FunctorBy t (Data.HBifunctor.Associative.WrapNE t f)) => Data.HBifunctor.Associative.SemigroupIn (Data.HBifunctor.Associative.WrapHBF t) (Data.HBifunctor.Associative.WrapNE t f) instance forall k1 k2 (t :: k1 -> k2 -> * -> *) (f :: k1) (g :: k2). Data.Functor.Classes.Show1 (t f g) => Data.Functor.Classes.Show1 (Data.HBifunctor.Associative.WrapHBF t f g) instance forall k1 k2 (t :: k1 -> k2 -> * -> *) (f :: k1) (g :: k2). Data.Functor.Classes.Eq1 (t f g) => Data.Functor.Classes.Eq1 (Data.HBifunctor.Associative.WrapHBF t f g) instance forall k1 k2 (t :: k1 -> k2 -> * -> *) (f :: k1) (g :: k2). Data.Functor.Classes.Ord1 (t f g) => Data.Functor.Classes.Ord1 (Data.HBifunctor.Associative.WrapHBF t f g) instance forall k (t :: (k -> *) -> (k -> *) -> k -> *). Data.HFunctor.Internal.HBifunctor t => Data.HFunctor.Internal.HBifunctor (Data.HBifunctor.Associative.WrapHBF t) instance Data.HBifunctor.Associative.Associative t => Data.HBifunctor.Associative.Associative (Data.HBifunctor.Associative.WrapHBF t) instance Data.Functor.Alt.Alt f => Data.HBifunctor.Associative.SemigroupIn (GHC.Generics.:*:) f instance Data.Functor.Alt.Alt f => Data.HBifunctor.Associative.SemigroupIn Data.Functor.Product.Product f instance Data.Functor.Bind.Class.Apply f => Data.HBifunctor.Associative.SemigroupIn Data.Functor.Day.Day f instance Data.Functor.Contravariant.Divise.Divise f => Data.HBifunctor.Associative.SemigroupIn Data.Functor.Contravariant.Day.Day f instance Data.Functor.Contravariant.Decide.Decide f => Data.HBifunctor.Associative.SemigroupIn Data.Functor.Contravariant.Night.Night f instance Data.HBifunctor.Associative.SemigroupIn (GHC.Generics.:+:) f instance Data.HBifunctor.Associative.SemigroupIn Data.Functor.Sum.Sum f instance Data.Functor.Alt.Alt f => Data.HBifunctor.Associative.SemigroupIn Data.Functor.These.These1 f instance Data.HBifunctor.Associative.SemigroupIn Control.Applicative.Step.Void3 f instance Data.Functor.Bind.Class.Bind f => Data.HBifunctor.Associative.SemigroupIn Control.Monad.Freer.Church.Comp f instance Data.HBifunctor.Associative.SemigroupIn Data.Bifunctor.Joker.Joker f instance Data.HBifunctor.Associative.SemigroupIn Data.HBifunctor.LeftF f instance Data.HBifunctor.Associative.SemigroupIn Data.HBifunctor.RightF f instance Data.HBifunctor.Associative.Associative (GHC.Generics.:*:) instance Data.HBifunctor.Associative.Associative Data.Functor.Product.Product instance Data.HBifunctor.Associative.Associative Data.Functor.Day.Day instance Data.HBifunctor.Associative.Associative Data.Functor.Contravariant.Day.Day instance Data.HBifunctor.Associative.Associative Data.Functor.Contravariant.Night.Night instance Data.HBifunctor.Associative.Associative (GHC.Generics.:+:) instance Data.HBifunctor.Associative.Associative Data.Functor.Sum.Sum instance Data.HBifunctor.Associative.Associative Data.Functor.These.These1 instance Data.HBifunctor.Associative.Associative Control.Applicative.Step.Void3 instance Data.HBifunctor.Associative.Associative Control.Monad.Freer.Church.Comp instance Data.HBifunctor.Associative.Associative Data.Bifunctor.Joker.Joker instance Data.HBifunctor.Associative.Associative Data.HBifunctor.LeftF instance Data.HBifunctor.Associative.Associative Data.HBifunctor.RightF -- | This module provides tools for working with binary functor -- combinators. -- -- Data.Functor.HFunctor deals with single functor -- combinators (transforming a single functor). This module provides -- tools for working with combinators that combine and mix two functors -- "together". -- -- The binary analog of HFunctor is HBifunctor: we can map -- a structure-transforming function over both of the transformed -- functors. -- -- Tensor gives some extra properties of your binary functor -- combinator: associativity and identity (see docs for Tensor for -- more details). -- -- The binary analog of Interpret is MonoidIn. If your -- combinator t and target functor f is an instance of -- MonoidIn t f, it means you can "interpret" out of your -- tensored values, and also "generate" values of f. -- --
-- biretract :: (f :+: f) a -> f a -- pureT :: V1 a -> f a -- -- biretract :: Plus f => (f :*: f) a -> f a -- pureT :: Plus f => Proxy a -> f a -- -- biretract :: Applicative f => Day f f a -> f a -- pureT :: Applicative f => Identity a -> f a -- -- biretract :: Monad f => Comp f f a -> f a -- pureT :: Monad f => Identity a -> f a --module Data.HBifunctor.Tensor -- | An Associative HBifunctor can be a Tensor if -- there is some identity i where t i f and t f -- i are equivalent to just f. -- -- That is, "enhancing" f with t i does nothing. -- -- The methods in this class provide us useful ways of navigating a -- Tensor t with respect to this property. -- -- The Tensor is essentially the HBifunctor equivalent of -- Inject, with intro1 and intro2 taking the place -- of inject. -- -- Formally, we can say that t enriches a the category of -- endofunctors with monoid strcture: it turns our endofunctor category -- into a "monoidal category". -- -- Different instances of t each enrich the endofunctor category -- in different ways, giving a different monoidal category. class (Associative t, Inject (ListBy t)) => Tensor t i | t -> i where { -- | The "monoidal functor combinator" induced by t. -- -- A value of type ListBy t f a is equivalent to one of: -- --
t f (t f (t f f)) a
t f (t f (t f (t f f))) a
-- Proxy ~ ListF [] ~ nilLB @(:*:)
-- x ~ ListF [x] ~ inject x
-- x :*: y ~ ListF [x,y] ~ toListBy (x :*: y)
-- x :*: y :*: z ~ ListF [x,y,z]
-- -- etc.
--
--
-- You can create an "empty" one with nilLB, a "singleton" one
-- with inject, or else one from a single t f f with
-- toListBy.
--
-- See NonEmptyBy for a "non-empty" version of this type.
type family ListBy t :: (Type -> Type) -> Type -> Type;
}
-- | Because t f (I t) is equivalent to f, we can always
-- "insert" f into t f (I t).
--
-- This is analogous to inject from Inject, but for
-- HBifunctors.
intro1 :: Tensor t i => f ~> t f i
-- | Because t (I t) g is equivalent to f, we can always
-- "insert" g into t (I t) g.
--
-- This is analogous to inject from Inject, but for
-- HBifunctors.
intro2 :: Tensor t i => g ~> t i g
-- | Witnesses the property that i is the identity of t:
-- t f i always leaves f unchanged, so we can always
-- just drop the i.
elim1 :: (Tensor t i, FunctorBy t f) => t f i ~> f
-- | Witnesses the property that i is the identity of t:
-- t i g always leaves g unchanged, so we can always
-- just drop the i t.
elim2 :: (Tensor t i, FunctorBy t g) => t i g ~> g
-- | If a ListBy t f represents multiple applications of
-- t f to itself, then we can also "append" two
-- ListBy t fs applied to themselves into one giant
-- ListBy t f containing all of the t fs.
--
-- Note that this essentially gives an instance for
-- SemigroupIn t (ListBy t f), for any functor
-- f; this is witnessed by WrapLB.
appendLB :: Tensor t i => t (ListBy t f) (ListBy t f) ~> ListBy t f
-- | Lets you convert an NonEmptyBy t f into a single
-- application of f to ListBy t f.
--
-- Analogous to a function NonEmpty a -> (a, [a])
--
-- Note that this is not reversible in general unless we have
-- Matchable t.
splitNE :: Tensor t i => NonEmptyBy t f ~> t f (ListBy t f)
-- | An ListBy t f is either empty, or a single application
-- of t to f and ListBy t f (the "head" and
-- "tail"). This witnesses that isomorphism.
--
-- To use this property, see nilLB, consLB, and
-- unconsLB.
splittingLB :: Tensor t i => ListBy t f <~> (i :+: t f (ListBy t f))
-- | Embed a direct application of f to itself into a
-- ListBy t f.
toListBy :: Tensor t i => t f f ~> ListBy t f
-- | NonEmptyBy t f is "one or more fs", and
-- 'ListBy t f is "zero or more fs". This function lets
-- us convert from one to the other.
--
-- This is analogous to a function NonEmpty a -> [a].
--
-- Note that because t is not inferrable from the input or
-- output type, you should call this using -XTypeApplications:
--
-- -- fromNE @(:*:) :: NonEmptyF f a -> ListF f a -- fromNE @Comp :: Free1 f a -> Free f a --fromNE :: Tensor t i => NonEmptyBy t f ~> ListBy t f -- | f is isomorphic to t f i: that is, i is the -- identity of t, and leaves f unchanged. rightIdentity :: (Tensor t i, FunctorBy t f) => f <~> t f i -- | g is isomorphic to t i g: that is, i is the -- identity of t, and leaves g unchanged. leftIdentity :: (Tensor t i, FunctorBy t g) => g <~> t i g -- | leftIdentity (intro1 and elim1) for :+: -- actually does not require Functor. This is the more general -- version. sumLeftIdentity :: f <~> (V1 :+: f) -- | rightIdentity (intro2 and elim2) for :+: -- actually does not require Functor. This is the more general -- version. sumRightIdentity :: f <~> (f :+: V1) -- | leftIdentity (intro1 and elim1) for :*: -- actually does not require Functor. This is the more general -- version. prodLeftIdentity :: f <~> (Proxy :*: f) -- | rightIdentity (intro2 and elim2) for :*: -- actually does not require Functor. This is the more general -- version. prodRightIdentity :: g <~> (g :*: Proxy) -- | This class effectively gives us a way to generate a value of f -- a based on an i a, for Tensor t i. -- Having this ability makes a lot of interesting functions possible when -- used with biretract from SemigroupIn that weren't -- possible without it: it gives us a "base case" for recursion in a lot -- of cases. -- -- Essentially, we get an i ~> f, pureT, where we can -- introduce an f a as long as we have an i a. -- -- Formally, if we have Tensor t i, we are enriching the -- category of endofunctors with monoid structure, turning it into a -- monoidal category. Different choices of t give different -- monoidal categories. -- -- A functor f is known as a "monoid in the (monoidal) category -- of endofunctors on t" if we can biretract: -- --
-- t f f ~> f ---- -- and also pureT: -- --
-- i ~> f ---- -- This gives us a few interesting results in category theory, which you -- can stil reading about if you don't care: -- --
-- instance Monad f => MonoidIn Comp Identity f ---- -- Any other sort of instance and it's easy to run into problems with -- type inference. If you want to write an instance that's "polymorphic" -- on tensor choice, use the WrapHBF and WrapF newtype -- wrappers over type variables, where the third argument also uses a -- type constructor: -- --
-- instance MonoidIn (WrapHBF t) (WrapF i) (MyFunctor t i) ---- -- This will prevent problems with overloaded instances. class (Tensor t i, SemigroupIn t f) => MonoidIn t i f -- | If we have an i, we can generate an f based on how -- it interacts with t. -- -- Specialized (and simplified), this type is: -- --
-- pureT @Day :: Applicative f => Identity a -> f a -- pure -- pureT @Comp :: Monad f => Identity a -> f a -- return -- pureT @(:*:) :: Plus f => Proxy a -> f a -- zero ---- -- Note that because t appears nowhere in the input or output -- types, you must always use this with explicit type application syntax -- (like pureT @Day) -- -- Along with biretract, this function makes f a monoid -- in the category of endofunctors with respect to tensor t. pureT :: MonoidIn t i f => i ~> f -- | If we have an i, we can generate an f based on how -- it interacts with t. -- -- Specialized (and simplified), this type is: -- --
-- pureT @Day :: Applicative f => Identity a -> f a -- pure -- pureT @Comp :: Monad f => Identity a -> f a -- return -- pureT @(:*:) :: Plus f => Proxy a -> f a -- zero ---- -- Note that because t appears nowhere in the input or output -- types, you must always use this with explicit type application syntax -- (like pureT @Day) -- -- Along with biretract, this function makes f a monoid -- in the category of endofunctors with respect to tensor t. pureT :: (MonoidIn t i f, Interpret (ListBy t) f) => i ~> f -- | Create the "empty ListBy". -- -- If ListBy t f represents multiple applications of -- t f with itself, then nilLB gives us "zero -- applications of f". -- -- Note that t cannot be inferred from the input or output type -- of nilLB, so this function must always be called with -- -XTypeApplications: -- --
-- nilLB @Day :: Identity ~> Ap f -- nilLB @Comp :: Identity ~> Free f -- nilLB @(:*:) :: Proxy ~> ListF f ---- -- Note that this essentially gives an instance for MonoidIn t -- i (ListBy t f), for any functor f; this is witnessed by -- WrapLB. nilLB :: forall t i f. Tensor t i => i ~> ListBy t f -- | Lets us "cons" an application of f to the front of an -- ListBy t f. consLB :: Tensor t i => t f (ListBy t f) ~> ListBy t f -- | "Pattern match" on an ListBy t -- -- An ListBy t f is either empty, or a single application -- of t to f and ListBy t f (the "head" and -- "tail") -- -- This is analogous to the function uncons :: [a] -> Maybe -- (a, [a]). unconsLB :: Tensor t i => ListBy t f ~> (i :+: t f (ListBy t f)) -- | An implementation of retract that works for any instance of -- MonoidIn t i for ListBy t. -- -- Can be useful as a default implementation if you already have -- MonoidIn implemented. retractLB :: forall t i f. MonoidIn t i f => ListBy t f ~> f -- | An implementation of interpret that works for any instance of -- MonoidIn t i for ListBy t. -- -- Can be useful as a default implementation if you already have -- MonoidIn implemented. interpretLB :: forall t i g f. MonoidIn t i f => (g ~> f) -> ListBy t g ~> f -- | Convenient wrapper over intro1 that lets us introduce an -- arbitrary functor g to the right of an f. -- -- You can think of this as an HBifunctor analogue of -- inject. inL :: forall t i f g. MonoidIn t i g => f ~> t f g -- | Convenient wrapper over intro2 that lets us introduce an -- arbitrary functor f to the right of a g. -- -- You can think of this as an HBifunctor analogue of -- inject. inR :: forall t i f g. MonoidIn t i f => g ~> t f g -- | Convenient wrapper over elim1 that lets us drop one of the -- arguments of a Tensor for free, without requiring any extra -- constraints (like for binterpret). -- -- See prodOutL for a version that does not require -- Functor f, specifically for :*:. outL :: (Tensor t Proxy, FunctorBy t f) => t f g ~> f -- | Convenient wrapper over elim2 that lets us drop one of the -- arguments of a Tensor for free, without requiring any -- constraints (like for binterpret). -- -- See prodOutR for a version that does not require -- Functor g, specifically for :*:. outR :: (Tensor t Proxy, FunctorBy t g) => t f g ~> g -- | outL for :*: actually does not require Functor. -- This is the more general version. prodOutL :: (f :*: g) ~> f -- | outR for :*: actually does not require Functor. -- This is the more general version. prodOutR :: (f :*: g) ~> g -- | A newtype wrapper meant to be used to define polymorphic -- MonoidIn instances. See documentation for MonoidIn for -- more information. -- -- Please do not ever define an instance of MonoidIn "naked" on -- the third parameter: -- --
-- instance MonidIn (WrapHBF t) (WrapF i) f ---- -- As that would globally ruin everything using WrapHBF. newtype WrapF f a WrapF :: f a -> WrapF f a [unwrapF] :: WrapF f a -> f a -- | Any ListBy t f is a SemigroupIn t and -- a MonoidIn t i, if we have Tensor t i. -- This newtype wrapper witnesses that fact. We require a newtype wrapper -- to avoid overlapping instances. newtype WrapLB t f a WrapLB :: ListBy t f a -> WrapLB t f a [unwrapLB] :: WrapLB t f a -> ListBy t f a -- | For some t, we have the ability to "statically analyze" the -- ListBy t and pattern match and manipulate the -- structure without ever interpreting or retracting. These are -- Matchable. class Tensor t i => Matchable t i -- | The inverse of splitNE. A consing of f to -- ListBy t f is non-empty, so it can be represented as -- an NonEmptyBy t f. -- -- This is analogous to a function uncurry (:|) :: (a, -- [a]) -> NonEmpty a. unsplitNE :: (Matchable t i, FunctorBy t f) => t f (ListBy t f) ~> NonEmptyBy t f -- | "Pattern match" on an ListBy t f: it is either empty, -- or it is non-empty (and so can be an NonEmptyBy t f). -- -- This is analgous to a function nonEmpty :: [a] -> Maybe -- (NonEmpty a). -- -- Note that because t cannot be inferred from the input or -- output type, you should use this with -XTypeApplications: -- --
-- matchLB @Day :: Ap f a -> (Identity :+: Ap1 f) a ---- -- Note that you can recursively "unroll" a ListBy completely into -- a Chain by using unrollLB. matchLB :: (Matchable t i, FunctorBy t f) => ListBy t f ~> (i :+: NonEmptyBy t f) -- | An NonEmptyBy t f is isomorphic to an f -- consed with an ListBy t f, like how a -- NonEmpty a is isomorphic to (a, [a]). splittingNE :: (Matchable t i, FunctorBy t f) => NonEmptyBy t f <~> t f (ListBy t f) -- | An ListBy t f is isomorphic to either the empty case -- (i) or the non-empty case (NonEmptyBy t f), -- like how [a] is isomorphic to Maybe -- (NonEmpty a). matchingLB :: forall t i f. (Matchable t i, FunctorBy t f) => ListBy t f <~> (i :+: NonEmptyBy t f) instance forall k (f :: k -> *) (a :: k). (Data.Typeable.Internal.Typeable a, Data.Typeable.Internal.Typeable f, Data.Typeable.Internal.Typeable k, Data.Data.Data (f a)) => Data.Data.Data (Data.HBifunctor.Tensor.WrapF f a) instance forall k (f :: k -> *) (a :: k). GHC.Generics.Generic (Data.HBifunctor.Tensor.WrapF f a) instance Data.Traversable.Traversable f => Data.Traversable.Traversable (Data.HBifunctor.Tensor.WrapF f) instance Data.Foldable.Foldable f => Data.Foldable.Foldable (Data.HBifunctor.Tensor.WrapF f) instance GHC.Base.Functor f => GHC.Base.Functor (Data.HBifunctor.Tensor.WrapF f) instance forall k (f :: k -> *) (a :: k). GHC.Classes.Ord (f a) => GHC.Classes.Ord (Data.HBifunctor.Tensor.WrapF f a) instance forall k (f :: k -> *) (a :: k). GHC.Classes.Eq (f a) => GHC.Classes.Eq (Data.HBifunctor.Tensor.WrapF f a) instance forall k (f :: k -> *) (a :: k). GHC.Read.Read (f a) => GHC.Read.Read (Data.HBifunctor.Tensor.WrapF f a) instance forall k (f :: k -> *) (a :: k). GHC.Show.Show (f a) => GHC.Show.Show (Data.HBifunctor.Tensor.WrapF f a) instance GHC.Base.Functor (Data.HBifunctor.Tensor.ListBy t f) => GHC.Base.Functor (Data.HBifunctor.Tensor.WrapLB t f) instance Data.Functor.Contravariant.Contravariant (Data.HBifunctor.Tensor.ListBy t f) => Data.Functor.Contravariant.Contravariant (Data.HBifunctor.Tensor.WrapLB t f) instance Data.Functor.Invariant.Invariant (Data.HBifunctor.Tensor.ListBy t f) => Data.Functor.Invariant.Invariant (Data.HBifunctor.Tensor.WrapLB t f) instance (Data.HBifunctor.Tensor.Tensor t i, Data.HBifunctor.Associative.FunctorBy t f, Data.HBifunctor.Associative.FunctorBy t (Data.HBifunctor.Tensor.WrapLB t f)) => Data.HBifunctor.Associative.SemigroupIn (Data.HBifunctor.Associative.WrapHBF t) (Data.HBifunctor.Tensor.WrapLB t f) instance (Data.HBifunctor.Tensor.Tensor t i, Data.HBifunctor.Associative.FunctorBy t f, Data.HBifunctor.Associative.FunctorBy t (Data.HBifunctor.Tensor.WrapLB t f)) => Data.HBifunctor.Tensor.MonoidIn (Data.HBifunctor.Associative.WrapHBF t) (Data.HBifunctor.Tensor.WrapF i) (Data.HBifunctor.Tensor.WrapLB t f) instance Data.Functor.Classes.Show1 f => Data.Functor.Classes.Show1 (Data.HBifunctor.Tensor.WrapF f) instance Data.Functor.Classes.Eq1 f => Data.Functor.Classes.Eq1 (Data.HBifunctor.Tensor.WrapF f) instance Data.Functor.Classes.Ord1 f => Data.Functor.Classes.Ord1 (Data.HBifunctor.Tensor.WrapF f) instance Data.HBifunctor.Tensor.Tensor t i => Data.HBifunctor.Tensor.Tensor (Data.HBifunctor.Associative.WrapHBF t) (Data.HBifunctor.Tensor.WrapF i) instance Data.HBifunctor.Tensor.Matchable (GHC.Generics.:*:) Data.Proxy.Proxy instance Data.HBifunctor.Tensor.Matchable Data.Functor.Product.Product Data.Proxy.Proxy instance Data.HBifunctor.Tensor.Matchable Data.Functor.Day.Day Data.Functor.Identity.Identity instance Data.HBifunctor.Tensor.Matchable Data.Functor.Contravariant.Day.Day Data.Proxy.Proxy instance Data.HBifunctor.Tensor.Matchable Data.Functor.Contravariant.Night.Night Data.Functor.Contravariant.Night.Not instance Data.HBifunctor.Tensor.Matchable (GHC.Generics.:+:) GHC.Generics.V1 instance Data.HBifunctor.Tensor.Matchable Data.Functor.Sum.Sum GHC.Generics.V1 instance Data.Functor.Plus.Plus f => Data.HBifunctor.Tensor.MonoidIn (GHC.Generics.:*:) Data.Proxy.Proxy f instance Data.Functor.Plus.Plus f => Data.HBifunctor.Tensor.MonoidIn Data.Functor.Product.Product Data.Proxy.Proxy f instance (Data.Functor.Bind.Class.Apply f, GHC.Base.Applicative f) => Data.HBifunctor.Tensor.MonoidIn Data.Functor.Day.Day Data.Functor.Identity.Identity f instance (Data.Functor.Contravariant.Divise.Divise f, Data.Functor.Contravariant.Divisible.Divisible f) => Data.HBifunctor.Tensor.MonoidIn Data.Functor.Contravariant.Day.Day Data.Proxy.Proxy f instance Data.Functor.Contravariant.Conclude.Conclude f => Data.HBifunctor.Tensor.MonoidIn Data.Functor.Contravariant.Night.Night Data.Functor.Contravariant.Night.Not f instance Data.HBifunctor.Tensor.MonoidIn (GHC.Generics.:+:) GHC.Generics.V1 f instance Data.HBifunctor.Tensor.MonoidIn Data.Functor.Sum.Sum GHC.Generics.V1 f instance Data.Functor.Alt.Alt f => Data.HBifunctor.Tensor.MonoidIn Data.Functor.These.These1 GHC.Generics.V1 f instance (Data.Functor.Bind.Class.Bind f, GHC.Base.Monad f) => Data.HBifunctor.Tensor.MonoidIn Control.Monad.Freer.Church.Comp Data.Functor.Identity.Identity f instance Data.HBifunctor.Tensor.Tensor (GHC.Generics.:*:) Data.Proxy.Proxy instance Data.HBifunctor.Tensor.Tensor Data.Functor.Product.Product Data.Proxy.Proxy instance Data.HBifunctor.Tensor.Tensor Data.Functor.Day.Day Data.Functor.Identity.Identity instance Data.HBifunctor.Tensor.Tensor Data.Functor.Contravariant.Day.Day Data.Proxy.Proxy instance Data.HBifunctor.Tensor.Tensor Data.Functor.Contravariant.Night.Night Data.Functor.Contravariant.Night.Not instance Data.HBifunctor.Tensor.Tensor (GHC.Generics.:+:) GHC.Generics.V1 instance Data.HBifunctor.Tensor.Tensor Data.Functor.Sum.Sum GHC.Generics.V1 instance Data.HBifunctor.Tensor.Tensor Data.Functor.These.These1 GHC.Generics.V1 instance Data.HBifunctor.Tensor.Tensor Control.Monad.Freer.Church.Comp Data.Functor.Identity.Identity -- | This module provides an Interpretable data type of "linked list -- of tensor applications". -- -- The type Chain t, for any Tensor t, is -- meant to be the same as ListBy t (the monoidal functor -- combinator for t), and represents "zero or more" applications -- of f to t. -- -- The type Chain1 t, for any Associative -- t, is meant to be the same as NonEmptyBy t (the -- semigroupoidal functor combinator for t) and represents "one -- or more" applications of f to t. -- -- The advantage of using Chain and Chain1 over -- ListBy or NonEmptyBy is that they provide a universal -- interface for pattern matching and constructing such values, which may -- simplify working with new such functor combinators you might -- encounter. module Data.HFunctor.Chain -- | A useful construction that works like a "linked list" of t f -- applied to itself multiple times. That is, it contains t f f, -- t f (t f f), t f (t f (t f f)), etc, with f -- occuring zero or more times. It is meant to be the same as -- ListBy t. -- -- If t is Tensor, then it means we can "collapse" this -- linked list into some final type ListBy t -- (reroll), and also extract it back into a linked list -- (unroll). -- -- So, a value of type Chain t i f a is one of either: -- --
i a
f a
t f f a
t f (t f f) a
t f (t f (t f f)) a
-- Tensor t i => MonoidIn (WrapHBF t) (WrapF i) (Chain t i f) ---- -- where pureT is Done and biretract is -- appendChain. -- -- This construction is inspired by -- http://oleg.fi/gists/posts/2018-02-21-single-free.html data Chain t i f a Done :: i a -> Chain t i f a More :: t f (Chain t i f) a -> Chain t i f a -- | Recursively fold down a Chain. Provide a function on how to -- handle the "single f case" (nilLB), and how to handle -- the "combined t f g case", and this will fold the entire -- Chain t i) f into a single g. -- -- This is a catamorphism. foldChain :: forall t i f g. HBifunctor t => (i ~> g) -> (t f g ~> g) -> Chain t i f ~> g -- | Recursively build up a Chain. Provide a function that takes -- some starting seed g and returns either "done" (i) -- or "continue further" (t f g), and it will create a -- Chain t i f from a g. -- -- This is an anamorphism. unfoldChain :: forall t f (g :: Type -> Type) i. HBifunctor t => (g ~> (i :+: t f g)) -> g ~> Chain t i f -- | A type ListBy t is supposed to represent the -- successive application of ts to itself. unroll makes -- that successive application explicit, buy converting it to a literal -- Chain of applications of t to itself. -- --
-- unroll = unfoldChain unconsLB --unroll :: Tensor t i => ListBy t f ~> Chain t i f -- | A type ListBy t is supposed to represent the -- successive application of ts to itself. rerollNE takes -- an explicit Chain of applications of t to itself and -- rolls it back up into an ListBy t. -- --
-- reroll = foldChain nilLB consLB ---- -- Because t cannot be inferred from the input or output, you -- should call this with -XTypeApplications: -- --
-- reroll @Comp -- :: Chain Comp Identity f a -> Free f a --reroll :: forall t i f. Tensor t i => Chain t i f ~> ListBy t f -- | A type ListBy t is supposed to represent the -- successive application of ts to itself. The type -- Chain t i f is an actual concrete ADT that contains -- successive applications of t to itself, and you can pattern -- match on each layer. -- -- unrolling states that the two types are isormorphic. Use -- unroll and reroll to convert between the two. unrolling :: Tensor t i => ListBy t f <~> Chain t i f -- | Chain is a monoid with respect to t: we can "combine" -- them in an associative way. The identity here is anything made with -- the Done constructor. -- -- This is essentially biretract, but only requiring -- Tensor t i: it comes from the fact that -- Chain1 t i is the "free MonoidIn t i". -- pureT is Done. appendChain :: forall t i f. Tensor t i => t (Chain t i f) (Chain t i f) ~> Chain t i f -- | For completeness, an isomorphism between Chain and its two -- constructors, to match splittingLB. splittingChain :: Chain t i f <~> (i :+: t f (Chain t i f)) -- | Convert a tensor value pairing two fs into a two-item chain. chainPair :: Tensor t i => t f f ~> Chain t i f -- | Create a singleton chain injectChain :: Tensor t i => f ~> Chain t i f -- | An analogue of unconsLB: match one of the two constructors of a -- Chain. unconsChain :: Chain t i f ~> (i :+: t f (Chain t i f)) -- | A useful construction that works like a "non-empty linked list" of -- t f applied to itself multiple times. That is, it contains -- t f f, t f (t f f), t f (t f (t f f)), etc, -- with f occuring one or more times. It is meant to be -- the same as NonEmptyBy t. -- -- A Chain1 t f a is explicitly one of: -- --
f a
t f f a
t f (t f f) a
t f (t f (t f f)) a
-- Associative t => SemigroupIn (WrapHBF t) (Chain1 t f) ---- -- where biretract is appendChain1. -- -- You can fully "collapse" a Chain t i f into an -- f with retract, if you have MonoidIn t i -- f; this could be considered a fundamental property of -- monoid-ness. -- -- This construction is inspired by iteratees and machines. data Chain1 t f a Done1 :: f a -> Chain1 t f a More1 :: t f (Chain1 t f) a -> Chain1 t f a -- | Recursively fold down a Chain1. Provide a function on how to -- handle the "single f case" (inject), and how to handle -- the "combined t f g case", and this will fold the entire -- Chain1 t f into a single g. -- -- This is a catamorphism. foldChain1 :: forall t f g. HBifunctor t => (f ~> g) -> (t f g ~> g) -> Chain1 t f ~> g -- | Recursively build up a Chain1. Provide a function that takes -- some starting seed g and returns either "done" (f) -- or "continue further" (t f g), and it will create a -- Chain1 t f from a g. -- -- This is an anamorphism. unfoldChain1 :: forall t f (g :: Type -> Type). HBifunctor t => (g ~> (f :+: t f g)) -> g ~> Chain1 t f -- | A type NonEmptyBy t is supposed to represent the -- successive application of ts to itself. The type -- Chain1 t f is an actual concrete ADT that contains -- successive applications of t to itself, and you can pattern -- match on each layer. -- -- unrollingNE states that the two types are isormorphic. Use -- unrollNE and rerollNE to convert between the two. unrollingNE :: forall t f. (Associative t, FunctorBy t f) => NonEmptyBy t f <~> Chain1 t f -- | A type NonEmptyBy t is supposed to represent the -- successive application of ts to itself. unrollNE makes -- that successive application explicit, buy converting it to a literal -- Chain1 of applications of t to itself. -- --
-- unrollNE = unfoldChain1 matchNE --unrollNE :: (Associative t, FunctorBy t f) => NonEmptyBy t f ~> Chain1 t f -- | A type NonEmptyBy t is supposed to represent the -- successive application of ts to itself. rerollNE takes -- an explicit Chain1 of applications of t to itself and -- rolls it back up into an NonEmptyBy t. -- --
-- rerollNE = foldChain1 inject consNE --rerollNE :: Associative t => Chain1 t f ~> NonEmptyBy t f -- | Chain1 is a semigroup with respect to t: we can -- "combine" them in an associative way. -- -- This is essentially biretract, but only requiring -- Associative t: it comes from the fact that -- Chain1 t is the "free SemigroupIn t". appendChain1 :: forall t f. (Associative t, FunctorBy t f) => t (Chain1 t f) (Chain1 t f) ~> Chain1 t f -- | A Chain1 is "one or more linked fs", and a -- Chain is "zero or more linked fs". So, we can convert -- from a Chain1 to a Chain that always has at least one -- f. -- -- The result of this function always is made with More at the top -- level. fromChain1 :: Tensor t i => Chain1 t f ~> Chain t i f -- | For completeness, an isomorphism between Chain1 and its two -- constructors, to match matchNE. matchChain1 :: Chain1 t f ~> (f :+: t f (Chain1 t f)) -- | Convert a tensor value pairing two fs into a two-item chain. chain1Pair :: HBifunctor t => t f f ~> Chain1 t f -- | Create a singleton Chain1. injectChain1 :: f ~> Chain1 t f -- | A Chain1 t f is like a non-empty linked list of -- fs, and a Chain t i f is a possibly-empty -- linked list of fs. This witnesses the fact that the former is -- isomorphic to f consed to the latter. splittingChain1 :: forall t i f. (Matchable t i, FunctorBy t f) => Chain1 t f <~> t f (Chain t i f) -- | The "forward" function representing splittingChain1. Provided -- here as a separate function because it does not require -- Functor f. splitChain1 :: forall t i f. Tensor t i => Chain1 t f ~> t f (Chain t i f) -- | A Chain t i f is a linked list of fs, and a -- Chain1 t f is a non-empty linked list of fs. -- This witnesses the fact that a Chain t i f is either -- empty (i) or non-empty (Chain1 t f). matchingChain :: forall t i f. (Tensor t i, Matchable t i, FunctorBy t f) => Chain t i f <~> (i :+: Chain1 t f) -- | The "reverse" function representing matchingChain. Provided -- here as a separate function because it does not require -- Functor f. unmatchChain :: forall t i f. Tensor t i => (i :+: Chain1 t f) ~> Chain t i f instance forall k (t :: (k -> *) -> (k -> *) -> k -> *) (f :: k -> *) (a :: k). GHC.Generics.Generic (Data.HFunctor.Chain.Chain1 t f a) instance forall k (f :: k -> *) (a :: k) (t :: (k -> *) -> (k -> *) -> k -> *). (GHC.Classes.Eq (f a), GHC.Classes.Eq (t f (Data.HFunctor.Chain.Chain1 t f) a)) => GHC.Classes.Eq (Data.HFunctor.Chain.Chain1 t f a) instance forall k (f :: k -> *) (a :: k) (t :: (k -> *) -> (k -> *) -> k -> *). (GHC.Classes.Ord (f a), GHC.Classes.Ord (t f (Data.HFunctor.Chain.Chain1 t f) a)) => GHC.Classes.Ord (Data.HFunctor.Chain.Chain1 t f a) instance forall k (f :: k -> *) (a :: k) (t :: (k -> *) -> (k -> *) -> k -> *). (GHC.Show.Show (f a), GHC.Show.Show (t f (Data.HFunctor.Chain.Chain1 t f) a)) => GHC.Show.Show (Data.HFunctor.Chain.Chain1 t f a) instance forall k (f :: k -> *) (a :: k) (t :: (k -> *) -> (k -> *) -> k -> *). (GHC.Read.Read (f a), GHC.Read.Read (t f (Data.HFunctor.Chain.Chain1 t f) a)) => GHC.Read.Read (Data.HFunctor.Chain.Chain1 t f a) instance (GHC.Base.Functor f, GHC.Base.Functor (t f (Data.HFunctor.Chain.Chain1 t f))) => GHC.Base.Functor (Data.HFunctor.Chain.Chain1 t f) instance (Data.Foldable.Foldable f, Data.Foldable.Foldable (t f (Data.HFunctor.Chain.Chain1 t f))) => Data.Foldable.Foldable (Data.HFunctor.Chain.Chain1 t f) instance (Data.Traversable.Traversable f, Data.Traversable.Traversable (t f (Data.HFunctor.Chain.Chain1 t f))) => Data.Traversable.Traversable (Data.HFunctor.Chain.Chain1 t f) instance forall k1 k2 (i :: k1 -> *) (a :: k1) (t :: k2 -> (k1 -> *) -> k1 -> *) (f :: k2). (GHC.Classes.Eq (i a), GHC.Classes.Eq (t f (Data.HFunctor.Chain.Chain t i f) a)) => GHC.Classes.Eq (Data.HFunctor.Chain.Chain t i f a) instance forall k1 k2 (i :: k1 -> *) (a :: k1) (t :: k2 -> (k1 -> *) -> k1 -> *) (f :: k2). (GHC.Classes.Ord (i a), GHC.Classes.Ord (t f (Data.HFunctor.Chain.Chain t i f) a)) => GHC.Classes.Ord (Data.HFunctor.Chain.Chain t i f a) instance forall k1 k2 (i :: k1 -> *) (a :: k1) (t :: k2 -> (k1 -> *) -> k1 -> *) (f :: k2). (GHC.Show.Show (i a), GHC.Show.Show (t f (Data.HFunctor.Chain.Chain t i f) a)) => GHC.Show.Show (Data.HFunctor.Chain.Chain t i f a) instance forall k1 k2 (i :: k1 -> *) (a :: k1) (t :: k2 -> (k1 -> *) -> k1 -> *) (f :: k2). (GHC.Read.Read (i a), GHC.Read.Read (t f (Data.HFunctor.Chain.Chain t i f) a)) => GHC.Read.Read (Data.HFunctor.Chain.Chain t i f a) instance forall k (i :: * -> *) (t :: k -> (* -> *) -> * -> *) (f :: k). (GHC.Base.Functor i, GHC.Base.Functor (t f (Data.HFunctor.Chain.Chain t i f))) => GHC.Base.Functor (Data.HFunctor.Chain.Chain t i f) instance forall k (i :: * -> *) (t :: k -> (* -> *) -> * -> *) (f :: k). (Data.Foldable.Foldable i, Data.Foldable.Foldable (t f (Data.HFunctor.Chain.Chain t i f))) => Data.Foldable.Foldable (Data.HFunctor.Chain.Chain t i f) instance forall k (i :: * -> *) (t :: k -> (* -> *) -> * -> *) (f :: k). (Data.Traversable.Traversable i, Data.Traversable.Traversable (t f (Data.HFunctor.Chain.Chain t i f))) => Data.Traversable.Traversable (Data.HFunctor.Chain.Chain t i f) instance forall k (i :: * -> *) (t :: k -> (* -> *) -> * -> *) (f :: k). (Data.Functor.Classes.Eq1 i, Data.Functor.Classes.Eq1 (t f (Data.HFunctor.Chain.Chain t i f))) => Data.Functor.Classes.Eq1 (Data.HFunctor.Chain.Chain t i f) instance forall k (i :: * -> *) (t :: k -> (* -> *) -> * -> *) (f :: k). (Data.Functor.Classes.Ord1 i, Data.Functor.Classes.Ord1 (t f (Data.HFunctor.Chain.Chain t i f))) => Data.Functor.Classes.Ord1 (Data.HFunctor.Chain.Chain t i f) instance forall k (t :: k -> (* -> *) -> * -> *) (f :: k) (i :: * -> *). (Data.Functor.Classes.Show1 (t f (Data.HFunctor.Chain.Chain t i f)), Data.Functor.Classes.Show1 i) => Data.Functor.Classes.Show1 (Data.HFunctor.Chain.Chain t i f) instance forall k (i :: * -> *) (t :: k -> (* -> *) -> * -> *) (f :: k). (GHC.Base.Functor i, Data.Functor.Classes.Read1 (t f (Data.HFunctor.Chain.Chain t i f)), Data.Functor.Classes.Read1 i) => Data.Functor.Classes.Read1 (Data.HFunctor.Chain.Chain t i f) instance forall k (i :: * -> *) (t :: k -> (* -> *) -> * -> *) (f :: k). (Data.Functor.Contravariant.Contravariant i, Data.Functor.Contravariant.Contravariant (t f (Data.HFunctor.Chain.Chain t i f))) => Data.Functor.Contravariant.Contravariant (Data.HFunctor.Chain.Chain t i f) instance forall k (i :: * -> *) (t :: k -> (* -> *) -> * -> *) (f :: k). (Data.Functor.Invariant.Invariant i, Data.Functor.Invariant.Invariant (t f (Data.HFunctor.Chain.Chain t i f))) => Data.Functor.Invariant.Invariant (Data.HFunctor.Chain.Chain t i f) instance forall k (t :: (k -> *) -> (k -> *) -> k -> *) (i :: k -> *). Data.HFunctor.Internal.HBifunctor t => Data.HFunctor.Internal.HFunctor (Data.HFunctor.Chain.Chain t i) instance Data.HBifunctor.Tensor.Tensor t i => Data.HFunctor.Inject (Data.HFunctor.Chain.Chain t i) instance Data.HBifunctor.Tensor.MonoidIn t i f => Data.HFunctor.Interpret.Interpret (Data.HFunctor.Chain.Chain t i) f instance (Data.HBifunctor.Tensor.Tensor t i, Data.HBifunctor.Associative.FunctorBy t (Data.HFunctor.Chain.Chain t i f)) => Data.HBifunctor.Associative.SemigroupIn (Data.HBifunctor.Associative.WrapHBF t) (Data.HFunctor.Chain.Chain t i f) instance (Data.HBifunctor.Tensor.Tensor t i, Data.HBifunctor.Associative.FunctorBy t (Data.HFunctor.Chain.Chain t i f)) => Data.HBifunctor.Tensor.MonoidIn (Data.HBifunctor.Associative.WrapHBF t) (Data.HBifunctor.Tensor.WrapF i) (Data.HFunctor.Chain.Chain t i f) instance Data.Functor.Bind.Class.Apply (Data.HFunctor.Chain.Chain Data.Functor.Day.Day Data.Functor.Identity.Identity f) instance GHC.Base.Applicative (Data.HFunctor.Chain.Chain Data.Functor.Day.Day Data.Functor.Identity.Identity f) instance Data.Functor.Contravariant.Divise.Divise (Data.HFunctor.Chain.Chain Data.Functor.Contravariant.Day.Day Data.Proxy.Proxy f) instance Data.Functor.Contravariant.Divisible.Divisible (Data.HFunctor.Chain.Chain Data.Functor.Contravariant.Day.Day Data.Proxy.Proxy f) instance Data.Functor.Contravariant.Decide.Decide (Data.HFunctor.Chain.Chain Data.Functor.Contravariant.Night.Night Data.Functor.Contravariant.Night.Not f) instance Data.Functor.Contravariant.Conclude.Conclude (Data.HFunctor.Chain.Chain Data.Functor.Contravariant.Night.Night Data.Functor.Contravariant.Night.Not f) instance Data.Functor.Bind.Class.Apply (Data.HFunctor.Chain.Chain Control.Monad.Freer.Church.Comp Data.Functor.Identity.Identity f) instance GHC.Base.Applicative (Data.HFunctor.Chain.Chain Control.Monad.Freer.Church.Comp Data.Functor.Identity.Identity f) instance Data.Functor.Bind.Class.Bind (Data.HFunctor.Chain.Chain Control.Monad.Freer.Church.Comp Data.Functor.Identity.Identity f) instance GHC.Base.Monad (Data.HFunctor.Chain.Chain Control.Monad.Freer.Church.Comp Data.Functor.Identity.Identity f) instance GHC.Base.Functor f => Data.Functor.Alt.Alt (Data.HFunctor.Chain.Chain (GHC.Generics.:*:) Data.Proxy.Proxy f) instance GHC.Base.Functor f => Data.Functor.Plus.Plus (Data.HFunctor.Chain.Chain (GHC.Generics.:*:) Data.Proxy.Proxy f) instance GHC.Base.Functor f => Data.Functor.Alt.Alt (Data.HFunctor.Chain.Chain Data.Functor.Product.Product Data.Proxy.Proxy f) instance GHC.Base.Functor f => Data.Functor.Plus.Plus (Data.HFunctor.Chain.Chain Data.Functor.Product.Product Data.Proxy.Proxy f) instance (Data.Functor.Classes.Eq1 f, Data.Functor.Classes.Eq1 (t f (Data.HFunctor.Chain.Chain1 t f))) => Data.Functor.Classes.Eq1 (Data.HFunctor.Chain.Chain1 t f) instance (Data.Functor.Classes.Ord1 f, Data.Functor.Classes.Ord1 (t f (Data.HFunctor.Chain.Chain1 t f))) => Data.Functor.Classes.Ord1 (Data.HFunctor.Chain.Chain1 t f) instance (Data.Functor.Classes.Show1 (t f (Data.HFunctor.Chain.Chain1 t f)), Data.Functor.Classes.Show1 f) => Data.Functor.Classes.Show1 (Data.HFunctor.Chain.Chain1 t f) instance (GHC.Base.Functor f, Data.Functor.Classes.Read1 (t f (Data.HFunctor.Chain.Chain1 t f)), Data.Functor.Classes.Read1 f) => Data.Functor.Classes.Read1 (Data.HFunctor.Chain.Chain1 t f) instance (Data.Functor.Contravariant.Contravariant f, Data.Functor.Contravariant.Contravariant (t f (Data.HFunctor.Chain.Chain1 t f))) => Data.Functor.Contravariant.Contravariant (Data.HFunctor.Chain.Chain1 t f) instance (Data.Functor.Invariant.Invariant f, Data.Functor.Invariant.Invariant (t f (Data.HFunctor.Chain.Chain1 t f))) => Data.Functor.Invariant.Invariant (Data.HFunctor.Chain.Chain1 t f) instance forall k (t :: (k -> *) -> (k -> *) -> k -> *). Data.HFunctor.Internal.HBifunctor t => Data.HFunctor.Internal.HFunctor (Data.HFunctor.Chain.Chain1 t) instance forall k (t :: (k -> *) -> (k -> *) -> k -> *). Data.HFunctor.Internal.HBifunctor t => Data.HFunctor.Inject (Data.HFunctor.Chain.Chain1 t) instance (Data.HFunctor.Internal.HBifunctor t, Data.HBifunctor.Associative.SemigroupIn t f) => Data.HFunctor.Interpret.Interpret (Data.HFunctor.Chain.Chain1 t) f instance (Data.HBifunctor.Associative.Associative t, Data.HBifunctor.Associative.FunctorBy t f, Data.HBifunctor.Associative.FunctorBy t (Data.HFunctor.Chain.Chain1 t f)) => Data.HBifunctor.Associative.SemigroupIn (Data.HBifunctor.Associative.WrapHBF t) (Data.HFunctor.Chain.Chain1 t f) instance GHC.Base.Functor f => Data.Functor.Bind.Class.Apply (Data.HFunctor.Chain.Chain1 Data.Functor.Day.Day f) instance GHC.Base.Functor f => Data.Functor.Bind.Class.Apply (Data.HFunctor.Chain.Chain1 Control.Monad.Freer.Church.Comp f) instance GHC.Base.Functor f => Data.Functor.Bind.Class.Bind (Data.HFunctor.Chain.Chain1 Control.Monad.Freer.Church.Comp f) instance GHC.Base.Functor f => Data.Functor.Alt.Alt (Data.HFunctor.Chain.Chain1 (GHC.Generics.:*:) f) instance GHC.Base.Functor f => Data.Functor.Alt.Alt (Data.HFunctor.Chain.Chain1 Data.Functor.Product.Product f) instance Data.Functor.Contravariant.Contravariant f => Data.Functor.Contravariant.Divise.Divise (Data.HFunctor.Chain.Chain1 Data.Functor.Contravariant.Day.Day f) instance Data.Functor.Contravariant.Contravariant f => Data.Functor.Contravariant.Decide.Decide (Data.HFunctor.Chain.Chain1 Data.Functor.Contravariant.Night.Night f) -- | Provides an Invariant version of a Day convolution over -- Either. module Data.Functor.Invariant.Night -- | A pairing of invariant functors to create a new invariant functor that -- represents the "choice" between the two. -- -- A Night f g a is a invariant "consumer" and "producer" -- of a, and it does this by either feeding the a to -- f, or feeding the a to g, and then -- collecting the result from whichever one it was fed to. Which decision -- of which path to takes happens at runtime depending what -- a is actually given. -- -- For example, if we have x :: f a and y :: g b, then -- night x y :: Night f g (Either a b). -- This is a consumer/producer of Either a bs, and it -- consumes Left branches by feeding it to x, and -- Right branches by feeding it to y. It then passes back -- the single result from the one of the two that was chosen. -- -- Mathematically, this is a invariant day convolution, except with a -- different choice of bifunctor (Either) than the typical one we -- talk about in Haskell (which uses (,)). Therefore, it is an -- alternative to the typical Day convolution --- hence, the name -- Night. data Night :: (Type -> Type) -> (Type -> Type) -> (Type -> Type) [Night] :: f b -> g c -> (a -> Either b c) -> (b -> a) -> (c -> a) -> Night f g a -- | A value of type Not a is "proof" that a is -- uninhabited. newtype Not a Not :: (a -> Void) -> Not a [refute] :: Not a -> a -> Void -- | Pair two invariant actions together into a Night; assigns the -- first one to Left inputs and outputs and the second one to -- Right inputs and outputs. night :: f a -> g b -> Night f g (Either a b) -- | Interpret the covariant part of a Night into a target context -- h, as long as the context is an instance of Alt. The -- Alt is used to combine results back together, chosen by -- <!>. runNightAlt :: forall f g h. Alt h => (f ~> h) -> (g ~> h) -> Night f g ~> h -- | Interpret the contravariant part of a Night into a target -- context h, as long as the context is an instance of -- Decide. The Decide is used to pick which part to feed -- the input to. runNightDecide :: forall f g h. Decide h => (f ~> h) -> (g ~> h) -> Night f g ~> h -- | Convert an invariant Night into the covariant version, dropping -- the contravariant part. -- -- Note that there is no covariant version of Night defined in any -- common library, so we use an equivalent type (if f and -- g are Functors) f :*: g. toCoNight :: (Functor f, Functor g) => Night f g ~> (f :*: g) -- | Convert an invariant Night into the contravariant version, -- dropping the covariant part. toContraNight :: Night f g ~> Night f g -- | Night is associative. assoc :: Night f (Night g h) ~> Night (Night f g) h -- | Night is associative. unassoc :: Night (Night f g) h ~> Night f (Night g h) -- | The left identity of Night is Not; this is one side of -- that isomorphism. intro1 :: g ~> Night Not g -- | The right identity of Night is Not; this is one side of -- that isomorphism. intro2 :: f ~> Night f Not -- | The left identity of Night is Not; this is one side of -- that isomorphism. elim1 :: Invariant g => Night Not g ~> g -- | The right identity of Night is Not; this is one side of -- that isomorphism. elim2 :: Invariant f => Night f Not ~> f -- | The two sides of a Night can be swapped. swapped :: Night f g ~> Night g f -- | Hoist a function over the left side of a Night. trans1 :: (f ~> h) -> Night f g ~> Night h g -- | Hoist a function over the right side of a Night. trans2 :: (g ~> h) -> Night f g ~> Night f h -- | Instead of defining yet another separate free monoid like Ap, -- Div, or Dec, we re-use Chain. -- -- You can assemble values using the combinators in -- Data.HFunctor.Chain, and then tear them down/interpret them -- using runCoNightChain and runContraNightChain. There is -- no general invariant interpreter (and so no MonoidIn instance -- for Night) because the typeclasses used to express the target -- contexts are probably not worth defining given how little the Haskell -- ecosystem uses invariant functors as an abstraction. type NightChain = Chain Night Not -- | Match on a non-empty NightChain; contains no fs, but -- only the terminal value. Analogous to the Choose constructor. pattern Share :: (a -> Either b c) -> (b -> a) -> (c -> a) -> f b -> NightChain f c -> NightChain f a -- | Match on an "empty" NightChain; contains no fs, but -- only the terminal value. Analogous to the Lose constructor. pattern Reject :: (a -> Void) -> NightChain f a -- | In the covariant direction, we can interpret out of a Chain of -- Night into any Plus. runCoNightChain :: forall f g. Plus g => (f ~> g) -> NightChain f ~> g -- | In the contravariant direction, we can interpret out of a Chain -- of Night into any Conclude. runContraNightChain :: forall f g. Conclude g => (f ~> g) -> NightChain f ~> g -- | Convenient wrapper to build up a NightChain on by providing -- each component of it. This makes it much easier to build up longer -- chains because you would only need to write the splitting/joining -- functions in one place. -- -- For example, if you had a data type -- --
-- data MyType = MTI Int | MTB Bool | MTS String ---- -- and an invariant functor Prim (representing, say, a -- bidirectional parser, where Prim Int is a bidirectional -- parser for an Int), then you could assemble a bidirectional -- parser for a MyType@ using: -- --
-- invmap (case MTI x -> Z (I x); MTB y -> S (Z (I y)); MTS z -> S (S (Z (I z)))) -- (case Z (I x) -> MTI x; S (Z (I y)) -> MTB y; S (S (Z (I z))) -> MTS z) $ -- assembleNightChain $ intPrim -- :* boolPrim -- :* stringPrim -- :* Nil ---- -- This is much more convenient than doing it using manual applications -- of decide or choose or Night, which would require -- manually peeling off eithers one-by-one. assembleNightChain :: NP f as -> NightChain f (NS I as) -- | A version of assembleNightChain where each component is itself -- a NightChain. -- --
-- assembleNightChain (x :* y :* z :* Nil) -- = concatNightChain (injectChain x :* injectChain y :* injectChain z :* Nil) --concatNightChain :: NP (NightChain f) as -> NightChain f (NS I as) -- | Instead of defining yet another separate free semigroup like -- Ap1, Div1, or Dec1, we re-use Chain1. -- -- You can assemble values using the combinators in -- Data.HFunctor.Chain, and then tear them down/interpret them -- using runCoNightChain1 and runContraNightChain1. There -- is no general invariant interpreter (and so no SemigroupIn -- instance for Night) because the typeclasses used to express the -- target contexts are probably not worth defining given how little the -- Haskell ecosystem uses invariant functors as an abstraction. type NightChain1 = Chain1 Night -- | Match on a NightChain1 to get the head and the rest of the -- items. Analogous to the Dec1 constructor. pattern NightChain1 :: Invariant f => (a -> Either b c) -> (b -> a) -> (c -> a) -> f b -> NightChain f c -> NightChain1 f a -- | In the covariant direction, we can interpret out of a Chain1 of -- Night into any Alt. runCoNightChain1 :: forall f g. Alt g => (f ~> g) -> NightChain1 f ~> g -- | In the contravariant direction, we can interpret out of a -- Chain1 of Night into any Decide. runContraNightChain1 :: forall f g. Decide g => (f ~> g) -> NightChain1 f ~> g -- | A version of assembleNightChain but for NightChain1 -- instead. Can be useful if you intend on interpreting it into something -- with only a Decide or Alt instance, but no -- Decidable or Plus or Alternative. assembleNightChain1 :: Invariant f => NP f (a : as) -> NightChain1 f (NS I (a : as)) -- | A version of concatNightChain but for NightChain1 -- instead. Can be useful if you intend on interpreting it into something -- with only a Decide or Alt instance, but no -- Decidable or Plus or Alternative. concatNightChain1 :: Invariant f => NP (NightChain1 f) (a : as) -> NightChain1 f (NS I (a : as)) instance Data.HBifunctor.Associative.Associative Data.Functor.Invariant.Night.Night instance Data.HBifunctor.Tensor.Tensor Data.Functor.Invariant.Night.Night Data.Functor.Contravariant.Night.Not instance Data.Functor.Invariant.Invariant (Data.Functor.Invariant.Night.Night f g) instance Data.HFunctor.Internal.HFunctor (Data.Functor.Invariant.Night.Night f) instance Data.HFunctor.Internal.HBifunctor Data.Functor.Invariant.Night.Night instance Data.HBifunctor.Tensor.Matchable Data.Functor.Invariant.Night.Night Data.Functor.Contravariant.Night.Not -- | Provides an Invariant version of the typical Haskell Day -- convolution over tuples. module Data.Functor.Invariant.Day -- | A pairing of invariant functors to create a new invariant functor that -- represents the "combination" between the two. -- -- A Day f g a is a invariant "consumer" and "producer" -- of a, and it does this by taking the a and feeding -- it to both f and g, and aggregating back the -- results. -- -- For example, if we have x :: f a and y :: g b, then -- day x y :: Day f g (a, b). This is a -- consumer/producer of (a, b)s, and it feeds the a to -- x and the b to y, and tuples the results -- back together. -- -- Mathematically, this is a invariant day convolution along a tuple. data Day :: (Type -> Type) -> (Type -> Type) -> (Type -> Type) [Day] :: f b -> g c -> (a -> (b, c)) -> (b -> c -> a) -> Day f g a -- | Pair two invariant actions together in a way that tuples together -- their input/outputs. The first one will take the fst part of -- the tuple, and the second one will take the snd part of the -- tuple. day :: f a -> g b -> Day f g (a, b) -- | Interpret the covariant part of a Day into a target context -- h, as long as the context is an instance of Apply. The -- Apply is used to combine results back together using -- <*>. runDayApply :: forall f g h. Apply h => (f ~> h) -> (g ~> h) -> Day f g ~> h -- | Interpret the contravariant part of a Day into a target context -- h, as long as the context is an instance of Divise. -- The Divise is used to split up the input to pass to each of the -- actions. runDayDivise :: forall f g h. Divise h => (f ~> h) -> (g ~> h) -> Day f g ~> h -- | Convert an invariant Day into the covariant version, dropping -- the contravariant part. toCoDay :: Day f g ~> Day f g -- | Convert an invariant Day into the contravariant version, -- dropping the covariant part. toContraDay :: Day f g ~> Day f g -- | Day is associative. assoc :: Day f (Day g h) ~> Day (Day f g) h -- | Day is associative. unassoc :: Day (Day f g) h ~> Day f (Day g h) -- | The left identity of Day is Identity; this is one side -- of that isomorphism. intro1 :: g ~> Day Identity g -- | The right identity of Day is Identity; this is one side -- of that isomorphism. intro2 :: f ~> Day f Identity -- | The left identity of Day is Identity; this is one side -- of that isomorphism. elim1 :: Invariant g => Day Identity g ~> g -- | The right identity of Day is Identity; this is one side -- of that isomorphism. elim2 :: Invariant f => Day f Identity ~> f -- | The two sides of a Day can be swapped. swapped :: Day f g ~> Day g f -- | Hoist a function over the left side of a Day. trans1 :: (f ~> h) -> Day f g ~> Day h g -- | Hoist a function over the right side of a Day. trans2 :: (g ~> h) -> Day f g ~> Day f h -- | Instead of defining yet another separate free monoid like Ap, -- Div, or Dec, we re-use Chain. -- -- You can assemble values using the combinators in -- Data.HFunctor.Chain, and then tear them down/interpret them -- using runCoDayChain and runContraDayChain. There is no -- general invariant interpreter (and so no MonoidIn instance for -- Day) because the typeclasses used to express the target -- contexts are probably not worth defining given how little the Haskell -- ecosystem uses invariant functors as an abstraction. type DayChain = Chain Day Identity -- | Match on a non-empty DayChain; contains no fs, but -- only the terminal value. Analogous to the Ap constructor. pattern Gather :: (a -> (b, c)) -> (b -> c -> a) -> f b -> DayChain f c -> DayChain f a -- | Match on an "empty" DayChain; contains no fs, but only -- the terminal value. Analogous to Pure. pattern Knot :: a -> DayChain f a -- | In the covariant direction, we can interpret out of a Chain of -- Day into any Applicative. runCoDayChain :: forall f g. Applicative g => (f ~> g) -> DayChain f ~> g -- | In the contravariant direction, we can interpret out of a Chain -- of Day into any Divisible. runContraDayChain :: forall f g. Divisible g => (f ~> g) -> DayChain f ~> g -- | Convenient wrapper to build up a DayChain by providing each -- component of it. This makes it much easier to build up longer chains -- because you would only need to write the splitting/joining functions -- in one place. -- -- For example, if you had a data type -- --
-- data MyType = MT Int Bool String ---- -- and an invariant functor Prim (representing, say, a -- bidirectional parser, where Prim Int is a bidirectional -- parser for an Int), then you could assemble a bidirectional -- parser for a MyType@ using: -- --
-- invmap ((MyType x y z) -> I x :* I y :* I z :* Nil) -- ((I x :* I y :* I z :* Nil) -> MyType x y z) $ -- assembleDayChain $ intPrim -- :* boolPrim -- :* stringPrim -- :* Nil ---- -- This is much more convenient than doing it using manual applications -- of divide or divise or Day, which would require -- manually peeling off tuples one-by-one. assembleDayChain :: NP f as -> DayChain f (NP I as) -- | A version of assembleDayChain using XRec from -- vinyl instead of NP from sop-core. This can be -- more convenient because it doesn't require manual unwrapping/wrapping -- of components. -- --
-- data MyType = MT Int Bool String -- -- invmap ((MyType x y z) -> x ::& y ::& z ::& RNil) -- ((x ::& y ::& z ::& RNil) -> MyType x y z) $ -- assembleDayChainRec $ intPrim -- :& boolPrim -- :& stringPrim -- :& Nil --assembleDayChainRec :: Rec f as -> DayChain f (XRec Identity as) -- | A version of assembleDayChain where each component is itself a -- DayChain. -- --
-- assembleDayChain (x :* y :* z :* Nil) -- = concatDayChain (injectChain x :* injectChain y :* injectChain z :* Nil) --concatDayChain :: NP (DayChain f) as -> DayChain f (NP I as) -- | A version of concatDayChain using XRec from vinyl -- instead of NP from sop-core. This can be more convenient -- because it doesn't require manual unwrapping/wrapping of components. concatDayChainRec :: Rec (DayChain f) as -> DayChain f (XRec Identity as) -- | Instead of defining yet another separate free semigroup like -- Ap1, Div1, or Dec1, we re-use Chain1. -- -- You can assemble values using the combinators in -- Data.HFunctor.Chain, and then tear them down/interpret them -- using runCoDayChain1 and runContraDayChain1. There is no -- general invariant interpreter (and so no SemigroupIn instance -- for Day) because the typeclasses used to express the target -- contexts are probably not worth defining given how little the Haskell -- ecosystem uses invariant functors as an abstraction. type DayChain1 = Chain1 Day -- | Match on a DayChain1 to get the head and the rest of the items. -- Analogous to the Ap1 constructor. pattern DayChain1 :: Invariant f => (a -> (b, c)) -> (b -> c -> a) -> f b -> DayChain f c -> DayChain1 f a -- | In the covariant direction, we can interpret out of a Chain1 of -- Day into any Apply. runCoDayChain1 :: forall f g. Apply g => (f ~> g) -> DayChain1 f ~> g -- | In the contravariant direction, we can interpret out of a -- Chain1 of Day into any Divise. runContraDayChain1 :: forall f g. Divise g => (f ~> g) -> DayChain1 f ~> g -- | A version of assembleDayChain but for DayChain1 instead. -- Can be useful if you intend on interpreting it into something with -- only a Divise or Apply instance, but no Divisible -- or Applicative. assembleDayChain1 :: Invariant f => NP f (a : as) -> DayChain1 f (NP I (a : as)) -- | A version of assembleDayChain1 using XRec from -- vinyl instead of NP from sop-core. This can be -- more convenient because it doesn't require manual unwrapping/wrapping -- of components. assembleDayChain1Rec :: Invariant f => Rec f (a : as) -> DayChain1 f (XRec Identity (a : as)) -- | A version of concatDayChain but for DayChain1 instead. -- Can be useful if you intend on interpreting it into something with -- only a Divise or Apply instance, but no Divisible -- or Applicative. concatDayChain1 :: Invariant f => NP (DayChain1 f) (a : as) -> DayChain1 f (NP I (a : as)) -- | A version of concatDayChain1 using XRec from -- vinyl instead of NP from sop-core. This can be -- more convenient because it doesn't require manual unwrapping/wrapping -- of components. concatDayChain1Rec :: Invariant f => Rec (DayChain1 f) (a : as) -> DayChain1 f (XRec Identity (a : as)) instance Data.HBifunctor.Associative.Associative Data.Functor.Invariant.Day.Day instance Data.HBifunctor.Tensor.Tensor Data.Functor.Invariant.Day.Day Data.Functor.Identity.Identity instance Data.Functor.Invariant.Invariant (Data.Functor.Invariant.Day.Day f g) instance Data.HFunctor.Internal.HFunctor (Data.Functor.Invariant.Day.Day f) instance Data.HFunctor.Internal.HBifunctor Data.Functor.Invariant.Day.Day instance Data.HBifunctor.Tensor.Matchable Data.Functor.Invariant.Day.Day Data.Functor.Identity.Identity -- | Functor combinators and tools (typeclasses and utiility functions) to -- manipulate them. This is the main "entrypoint" of the library. -- -- Classes include: -- --
-- viewF :: (f <~> g) -> f a -> g a -- reviewF :: (f <~> g) -> g a -> a a ---- -- Use viewF to extract the "f to g" function, -- and reviewF to extract the "g to f" function. -- Reviewing and viewing the same value (or vice versa) leaves the value -- unchanged. -- -- One nice thing is that we can compose isomorphisms using . from -- Prelude: -- --
-- (.) :: f <~> g -- -> g <~> h -- -> f <~> h ---- -- Another nice thing about this representation is that we have the -- "identity" isomorphism by using id from Prelude. -- --
-- id :: f <~> g ---- -- As a convention, most isomorphisms have form "X-ing", where the -- forwards function is "ing". For example, we have: -- --
-- splittingSF :: Monoidal t => SF t a <~> t f (MF t f) -- splitSF :: Monoidal t => SF t a ~> t f (MF t f) --type f <~> g = forall p a. Profunctor p => p (g a) (g a) -> p (f a) (f a) infixr 0 <~> -- | An HFunctor can be thought of a unary "functor transformer" --- -- a basic functor combinator. It takes a functor as input and returns a -- functor as output. -- -- It "enhances" a functor with extra structure (sort of like how a monad -- transformer enhances a Monad with extra structure). -- -- As a uniform inteface, we can "swap the underlying functor" (also -- sometimes called "hoisting"). This is what hmap does: it lets -- us swap out the f in a t f for a t g. -- -- For example, the free monad Free takes a Functor and -- returns a new Functor. In the process, it provides a monadic -- structure over f. hmap lets us turn a Free -- f into a Free g: a monad built over f -- can be turned into a monad built over g. -- -- For the ability to move in and out of the enhanced functor, see -- Inject and Interpret. -- -- This class is similar to MFunctor from -- Control.Monad.Morph, but instances must work without a -- Monad constraint. -- -- This class is also found in the hschema library with the same -- name. class HFunctor t -- | If we can turn an f into a g, then we can turn a -- t f into a t g. -- -- It must be the case that -- --
-- hmap id == id ---- -- Essentially, t f adds some "extra structure" to f. -- hmap must swap out the functor, without affecting the added -- structure. -- -- For example, ListF f a is essentially a list of f -- as. If we hmap to swap out the f as for g -- as, then we must ensure that the "added structure" (here, the -- number of items in the list, and the ordering of those items) remains -- the same. So, hmap must preserve the number of items in the -- list, and must maintain the ordering. -- -- The law hmap id == id is a way of formalizing -- this property. hmap :: HFunctor t => (f ~> g) -> t f ~> t g -- | A typeclass for HFunctors where you can "inject" an f -- a into a t f a: -- --
-- inject :: f a -> t f a ---- -- If you think of t f a as an "enhanced f", then -- inject allows you to use an f as its enhanced form. -- -- With the exception of directly pattern matching on the result, -- inject itself is not too useful in the general case without -- Interpret to allow us to interpret or retrieve back the -- f. class HFunctor t => Inject t -- | Lift from f into the enhanced t f structure. -- Analogous to lift from MonadTrans. -- -- Note that this lets us "lift" a f a; if you want to lift an -- a with a -> t f a, check if t f is an -- instance of Applicative or Pointed. inject :: Inject t => f ~> t f -- | An Interpret lets us move in and out of the "enhanced" -- Functor (t f) and the functor it enhances -- (f). An instance Interpret t f means we have -- t f a -> f a. -- -- For example, Free f is f enhanced with -- monadic structure. We get: -- --
-- inject :: f a -> Free f a -- interpret :: Monad m => (forall x. f x -> m x) -> Free f a -> m a ---- -- inject will let us use our f inside the enhanced -- Free f. interpret will let us "extract" the -- f from a Free f if we can give an -- interpreting function that interprets f into some -- target Monad. -- -- We enforce that: -- --
-- interpret id . inject == id -- -- or -- retract . inject == id ---- -- That is, if we lift a value into our structure, then immediately -- interpret it out as itself, it should lave the value unchanged. -- -- Note that instances of this class are intended to be written -- with t as a fixed type constructor, and f to be -- allowed to vary freely: -- --
-- instance Monad f => Interpret Free f ---- -- Any other sort of instance and it's easy to run into problems with -- type inference. If you want to write an instance that's "polymorphic" -- on tensor choice, use the WrapHF newtype wrapper over a type -- variable, where the second argument also uses a type constructor: -- --
-- instance Interpret (WrapHF t) (MyFunctor t) ---- -- This will prevent problems with overloaded instances. class Inject t => Interpret t f -- | Remove the f out of the enhanced t f structure, -- provided that f satisfies the necessary constraints. If it -- doesn't, it needs to be properly interpreted out. retract :: Interpret t f => t f ~> f -- | Given an "interpeting function" from f to g, -- interpret the f out of the t f into a final context -- g. interpret :: Interpret t f => (g ~> f) -> t g ~> f -- | A convenient flipped version of interpret. forI :: Interpret t f => t g a -> (g ~> f) -> f a -- | Useful wrapper over interpret to allow you to directly extract -- a value b out of the t f a, if you can convert f -- x into b. -- -- Note that depending on the constraints on f in -- Interpret t f, you may have extra constraints on -- b. -- --
-- -- get the length of the Map String in the Step. -- collectI length -- :: Step (Map String) Bool -- -> Int --getI :: Interpret t (Const b) => (forall x. f x -> b) -> t f a -> b -- | Useful wrapper over getI to allow you to collect a b -- from all instances of f inside a t f a. -- -- Will work if there is an instance of Interpret t -- (Const [b]), which will be the case if the constraint on -- the target functor is Functor, Apply, -- Applicative, or unconstrianed. -- --
-- -- get the lengths of all Map Strings in the Ap. -- collectI length -- :: Ap (Map String) Bool -- -> [Int] --collectI :: Interpret t (Const [b]) => (forall x. f x -> b) -> t f a -> [b] -- | A HBifunctor is like an HFunctor, but it enhances -- two different functors instead of just one. -- -- Usually, it enhaces them "together" in some sort of combining way. -- -- This typeclass provides a uniform instance for "swapping out" or -- "hoisting" the enhanced functors. We can hoist the first one with -- hleft, the second one with hright, or both at the same -- time with hbimap. -- -- For example, the f :*: g type gives us "both f and -- g": -- --
-- data (f :*: g) a = f a :*: g a ---- -- It combines both f and g into a unified structure -- --- here, it does it by providing both f and g. -- -- The single law is: -- --
-- hbimap id id == id ---- -- This ensures that hleft, hright, and hbimap do -- not affect the structure that t adds on top of the underlying -- functors. class HBifunctor (t :: (k -> Type) -> (k -> Type) -> k -> Type) -- | Swap out the first transformed functor. hleft :: HBifunctor t => (f ~> j) -> t f g ~> t j g -- | Swap out the second transformed functor. hright :: HBifunctor t => (g ~> l) -> t f g ~> t f l -- | Swap out both transformed functors at the same time. hbimap :: HBifunctor t => (f ~> j) -> (g ~> l) -> t f g ~> t j l -- | An HBifunctor where it doesn't matter which binds first is -- Associative. Knowing this gives us a lot of power to rearrange -- the internals of our HFunctor at will. -- -- For example, for the functor product: -- --
-- data (f :*: g) a = f a :*: g a ---- -- We know that f :*: (g :*: h) is the same as (f :*: g) :*: -- h. -- -- Formally, we can say that t enriches a the category of -- endofunctors with semigroup strcture: it turns our endofunctor -- category into a "semigroupoidal category". -- -- Different instances of t each enrich the endofunctor category -- in different ways, giving a different semigroupoidal category. class (HBifunctor t, Inject (NonEmptyBy t)) => Associative t where { -- | The "semigroup functor combinator" generated by t. -- -- A value of type NonEmptyBy t f a is equivalent to one -- of: -- --
f a
t f f a
t f (t f f) a
t f (t f (t f f)) a
t f (t f (t f (t f f))) a
-- x ~ NonEmptyF (x :| []) ~ inject x
-- x :*: y ~ NonEmptyF (x :| [y]) ~ toNonEmptyBy (x :*: y)
-- x :*: y :*: z ~ NonEmptyF (x :| [y,z])
-- -- etc.
--
--
-- You can create an "singleton" one with inject, or else one from
-- a single t f f with toNonEmptyBy.
--
-- See ListBy for a "possibly empty" version of this type.
type family NonEmptyBy t :: (Type -> Type) -> Type -> Type;
-- | A description of "what type of Functor" this tensor is expected to be
-- applied to. This should typically always be either Functor,
-- Contravariant, or Invariant.
type family FunctorBy t :: (Type -> Type) -> Constraint;
type FunctorBy t = Unconstrained;
}
-- | The isomorphism between t f (t g h) a and t (t f g) h
-- a. To use this isomorphism, see assoc and disassoc.
associating :: (Associative t, FunctorBy t f, FunctorBy t g, FunctorBy t h) => t f (t g h) <~> t (t f g) h
-- | If a NonEmptyBy t f represents multiple applications
-- of t f to itself, then we can also "append" two
-- NonEmptyBy t fs applied to themselves into one giant
-- NonEmptyBy t f containing all of the t fs.
--
-- Note that this essentially gives an instance for
-- SemigroupIn t (NonEmptyBy t f), for any functor
-- f.
appendNE :: Associative t => t (NonEmptyBy t f) (NonEmptyBy t f) ~> NonEmptyBy t f
-- | If a NonEmptyBy t f represents multiple applications
-- of t f to itself, then we can split it based on whether or
-- not it is just a single f or at least one top-level
-- application of t f.
--
-- Note that you can recursively "unroll" a NonEmptyBy completely
-- into a Chain1 by using unrollNE.
matchNE :: (Associative t, FunctorBy t f) => NonEmptyBy t f ~> (f :+: t f (NonEmptyBy t f))
-- | Prepend an application of t f to the front of a
-- NonEmptyBy t f.
consNE :: Associative t => t f (NonEmptyBy t f) ~> NonEmptyBy t f
-- | Embed a direct application of f to itself into a
-- NonEmptyBy t f.
toNonEmptyBy :: Associative t => t f f ~> NonEmptyBy t f
-- | For different Associative t, we have functors
-- f that we can "squash", using biretract:
--
-- -- t f f ~> f ---- -- This gives us the ability to squash applications of t. -- -- Formally, if we have Associative t, we are enriching -- the category of endofunctors with semigroup structure, turning it into -- a semigroupoidal category. Different choices of t give -- different semigroupoidal categories. -- -- A functor f is known as a "semigroup in the (semigroupoidal) -- category of endofunctors on t" if we can biretract: -- --
-- t f f ~> f ---- -- This gives us a few interesting results in category theory, which you -- can stil reading about if you don't care: -- --
-- instance Bind f => SemigroupIn Comp f ---- -- Any other sort of instance and it's easy to run into problems with -- type inference. If you want to write an instance that's "polymorphic" -- on tensor choice, use the WrapHBF newtype wrapper over a type -- variable, where the second argument also uses a type constructor: -- --
-- instance SemigroupIn (WrapHBF t) (MyFunctor t i) ---- -- This will prevent problems with overloaded instances. class (Associative t, FunctorBy t f) => SemigroupIn t f -- | The HBifunctor analogy of retract. It retracts -- both fs into a single f, effectively fully -- mixing them together. -- -- This function makes f a semigroup in the category of -- endofunctors with respect to tensor t. biretract :: SemigroupIn t f => t f f ~> f -- | The HBifunctor analogy of retract. It retracts -- both fs into a single f, effectively fully -- mixing them together. -- -- This function makes f a semigroup in the category of -- endofunctors with respect to tensor t. biretract :: (SemigroupIn t f, Interpret (NonEmptyBy t) f) => t f f ~> f -- | The HBifunctor analogy of interpret. It takes two -- interpreting functions, and mixes them together into a target functor -- h. -- -- Note that this is useful in the poly-kinded case, but it is not -- possible to define generically for all SemigroupIn because it -- only is defined for Type -> Type inputes. See !+! -- for a version that is poly-kinded for :+: in specific. binterpret :: SemigroupIn t f => (g ~> f) -> (h ~> f) -> t g h ~> f -- | The HBifunctor analogy of interpret. It takes two -- interpreting functions, and mixes them together into a target functor -- h. -- -- Note that this is useful in the poly-kinded case, but it is not -- possible to define generically for all SemigroupIn because it -- only is defined for Type -> Type inputes. See !+! -- for a version that is poly-kinded for :+: in specific. binterpret :: (SemigroupIn t f, Interpret (NonEmptyBy t) f) => (g ~> f) -> (h ~> f) -> t g h ~> f -- | Useful wrapper over binterpret to allow you to directly extract -- a value b out of the t f a, if you can convert f -- x into b. -- -- Note that depending on the constraints on f in -- SemigroupIn t f, you may have extra constraints on -- b. -- --
-- -- Return the length of either the list, or the Map, depending on which -- -- one s in the + -- biget length length -- :: ([] :+: Map Int) Char -- -> Int -- -- -- Return the length of both the list and the map, added together -- biget (Sum . length) (Sum . length) -- :: Day [] (Map Int) Char -- -> Sum Int --biget :: SemigroupIn t (Const b) => (forall x. f x -> b) -> (forall x. g x -> b) -> t f g a -> b -- | Useful wrapper over biget to allow you to collect a b -- from all instances of f and g inside a t f g -- a. -- -- This will work if the constraint on f for -- SemigroupIn t f is Apply or Applicative, -- or if it is unconstrained. bicollect :: SemigroupIn t (Const [b]) => (forall x. f x -> b) -> (forall x. g x -> b) -> t f g a -> [b] -- | Infix alias for binterpret -- -- Note that this is useful in the poly-kinded case, but it is not -- possible to define generically for all SemigroupIn because it -- only is defined for Type -> Type inputes. See !+! -- for a version that is poly-kinded for :+: in specific. (!*!) :: SemigroupIn t h => (f ~> h) -> (g ~> h) -> t f g ~> h infixr 5 !*! -- | A version of !*! specifically for :+: that is -- poly-kinded (!+!) :: (f ~> h) -> (g ~> h) -> (f :+: g) ~> h infixr 5 !+! -- | Infix alias for biget -- --
-- -- Return the length of either the list, or the Map, depending on which -- -- one s in the + -- length !$! length -- :: ([] :+: Map Int) Char -- -> Int -- -- -- Return the length of both the list and the map, added together -- Sum . length !$! Sum . length -- :: Day [] (Map Int) Char -- -> Sum Int --(!$!) :: SemigroupIn t (Const b) => (forall x. f x -> b) -> (forall x. g x -> b) -> t f g a -> b infixr 5 !$! -- | An Associative HBifunctor can be a Tensor if -- there is some identity i where t i f and t f -- i are equivalent to just f. -- -- That is, "enhancing" f with t i does nothing. -- -- The methods in this class provide us useful ways of navigating a -- Tensor t with respect to this property. -- -- The Tensor is essentially the HBifunctor equivalent of -- Inject, with intro1 and intro2 taking the place -- of inject. -- -- Formally, we can say that t enriches a the category of -- endofunctors with monoid strcture: it turns our endofunctor category -- into a "monoidal category". -- -- Different instances of t each enrich the endofunctor category -- in different ways, giving a different monoidal category. class (Associative t, Inject (ListBy t)) => Tensor t i | t -> i where { -- | The "monoidal functor combinator" induced by t. -- -- A value of type ListBy t f a is equivalent to one of: -- --
t f (t f (t f f)) a
t f (t f (t f (t f f))) a
-- Proxy ~ ListF [] ~ nilLB @(:*:)
-- x ~ ListF [x] ~ inject x
-- x :*: y ~ ListF [x,y] ~ toListBy (x :*: y)
-- x :*: y :*: z ~ ListF [x,y,z]
-- -- etc.
--
--
-- You can create an "empty" one with nilLB, a "singleton" one
-- with inject, or else one from a single t f f with
-- toListBy.
--
-- See NonEmptyBy for a "non-empty" version of this type.
type family ListBy t :: (Type -> Type) -> Type -> Type;
}
-- | Because t f (I t) is equivalent to f, we can always
-- "insert" f into t f (I t).
--
-- This is analogous to inject from Inject, but for
-- HBifunctors.
intro1 :: Tensor t i => f ~> t f i
-- | Because t (I t) g is equivalent to f, we can always
-- "insert" g into t (I t) g.
--
-- This is analogous to inject from Inject, but for
-- HBifunctors.
intro2 :: Tensor t i => g ~> t i g
-- | Witnesses the property that i is the identity of t:
-- t f i always leaves f unchanged, so we can always
-- just drop the i.
elim1 :: (Tensor t i, FunctorBy t f) => t f i ~> f
-- | Witnesses the property that i is the identity of t:
-- t i g always leaves g unchanged, so we can always
-- just drop the i t.
elim2 :: (Tensor t i, FunctorBy t g) => t i g ~> g
-- | If a ListBy t f represents multiple applications of
-- t f to itself, then we can also "append" two
-- ListBy t fs applied to themselves into one giant
-- ListBy t f containing all of the t fs.
--
-- Note that this essentially gives an instance for
-- SemigroupIn t (ListBy t f), for any functor
-- f; this is witnessed by WrapLB.
appendLB :: Tensor t i => t (ListBy t f) (ListBy t f) ~> ListBy t f
-- | Lets you convert an NonEmptyBy t f into a single
-- application of f to ListBy t f.
--
-- Analogous to a function NonEmpty a -> (a, [a])
--
-- Note that this is not reversible in general unless we have
-- Matchable t.
splitNE :: Tensor t i => NonEmptyBy t f ~> t f (ListBy t f)
-- | An ListBy t f is either empty, or a single application
-- of t to f and ListBy t f (the "head" and
-- "tail"). This witnesses that isomorphism.
--
-- To use this property, see nilLB, consLB, and
-- unconsLB.
splittingLB :: Tensor t i => ListBy t f <~> (i :+: t f (ListBy t f))
-- | Embed a direct application of f to itself into a
-- ListBy t f.
toListBy :: Tensor t i => t f f ~> ListBy t f
-- | NonEmptyBy t f is "one or more fs", and
-- 'ListBy t f is "zero or more fs". This function lets
-- us convert from one to the other.
--
-- This is analogous to a function NonEmpty a -> [a].
--
-- Note that because t is not inferrable from the input or
-- output type, you should call this using -XTypeApplications:
--
-- -- fromNE @(:*:) :: NonEmptyF f a -> ListF f a -- fromNE @Comp :: Free1 f a -> Free f a --fromNE :: Tensor t i => NonEmptyBy t f ~> ListBy t f -- | This class effectively gives us a way to generate a value of f -- a based on an i a, for Tensor t i. -- Having this ability makes a lot of interesting functions possible when -- used with biretract from SemigroupIn that weren't -- possible without it: it gives us a "base case" for recursion in a lot -- of cases. -- -- Essentially, we get an i ~> f, pureT, where we can -- introduce an f a as long as we have an i a. -- -- Formally, if we have Tensor t i, we are enriching the -- category of endofunctors with monoid structure, turning it into a -- monoidal category. Different choices of t give different -- monoidal categories. -- -- A functor f is known as a "monoid in the (monoidal) category -- of endofunctors on t" if we can biretract: -- --
-- t f f ~> f ---- -- and also pureT: -- --
-- i ~> f ---- -- This gives us a few interesting results in category theory, which you -- can stil reading about if you don't care: -- --
-- instance Monad f => MonoidIn Comp Identity f ---- -- Any other sort of instance and it's easy to run into problems with -- type inference. If you want to write an instance that's "polymorphic" -- on tensor choice, use the WrapHBF and WrapF newtype -- wrappers over type variables, where the third argument also uses a -- type constructor: -- --
-- instance MonoidIn (WrapHBF t) (WrapF i) (MyFunctor t i) ---- -- This will prevent problems with overloaded instances. class (Tensor t i, SemigroupIn t f) => MonoidIn t i f -- | If we have an i, we can generate an f based on how -- it interacts with t. -- -- Specialized (and simplified), this type is: -- --
-- pureT @Day :: Applicative f => Identity a -> f a -- pure -- pureT @Comp :: Monad f => Identity a -> f a -- return -- pureT @(:*:) :: Plus f => Proxy a -> f a -- zero ---- -- Note that because t appears nowhere in the input or output -- types, you must always use this with explicit type application syntax -- (like pureT @Day) -- -- Along with biretract, this function makes f a monoid -- in the category of endofunctors with respect to tensor t. pureT :: MonoidIn t i f => i ~> f -- | If we have an i, we can generate an f based on how -- it interacts with t. -- -- Specialized (and simplified), this type is: -- --
-- pureT @Day :: Applicative f => Identity a -> f a -- pure -- pureT @Comp :: Monad f => Identity a -> f a -- return -- pureT @(:*:) :: Plus f => Proxy a -> f a -- zero ---- -- Note that because t appears nowhere in the input or output -- types, you must always use this with explicit type application syntax -- (like pureT @Day) -- -- Along with biretract, this function makes f a monoid -- in the category of endofunctors with respect to tensor t. pureT :: (MonoidIn t i f, Interpret (ListBy t) f) => i ~> f -- | Create the "empty ListBy". -- -- If ListBy t f represents multiple applications of -- t f with itself, then nilLB gives us "zero -- applications of f". -- -- Note that t cannot be inferred from the input or output type -- of nilLB, so this function must always be called with -- -XTypeApplications: -- --
-- nilLB @Day :: Identity ~> Ap f -- nilLB @Comp :: Identity ~> Free f -- nilLB @(:*:) :: Proxy ~> ListF f ---- -- Note that this essentially gives an instance for MonoidIn t -- i (ListBy t f), for any functor f; this is witnessed by -- WrapLB. nilLB :: forall t i f. Tensor t i => i ~> ListBy t f -- | Lets us "cons" an application of f to the front of an -- ListBy t f. consLB :: Tensor t i => t f (ListBy t f) ~> ListBy t f -- | Convenient wrapper over intro1 that lets us introduce an -- arbitrary functor g to the right of an f. -- -- You can think of this as an HBifunctor analogue of -- inject. inL :: forall t i f g. MonoidIn t i g => f ~> t f g -- | Convenient wrapper over intro2 that lets us introduce an -- arbitrary functor f to the right of a g. -- -- You can think of this as an HBifunctor analogue of -- inject. inR :: forall t i f g. MonoidIn t i f => g ~> t f g -- | Convenient wrapper over elim1 that lets us drop one of the -- arguments of a Tensor for free, without requiring any extra -- constraints (like for binterpret). -- -- See prodOutL for a version that does not require -- Functor f, specifically for :*:. outL :: (Tensor t Proxy, FunctorBy t f) => t f g ~> f -- | Convenient wrapper over elim2 that lets us drop one of the -- arguments of a Tensor for free, without requiring any -- constraints (like for binterpret). -- -- See prodOutR for a version that does not require -- Functor g, specifically for :*:. outR :: (Tensor t Proxy, FunctorBy t g) => t f g ~> g -- | A covariant Functor suitable for Yoneda reduction data Coyoneda (f :: Type -> Type) a [Coyoneda] :: forall b a (f :: Type -> Type). (b -> a) -> f b -> Coyoneda f a -- | A list of f as. Can be used to describe a product of many -- different values of type f a. -- -- This is the Free Plus. -- -- Incidentally, if used with a Contravariant f, this is -- instead the free Divisible. newtype ListF f a ListF :: [f a] -> ListF f a [runListF] :: ListF f a -> [f a] -- | A non-empty list of f as. Can be used to describe a product -- between many different possible values of type f a. -- -- Essentially: -- --
-- NonEmptyF f -- ~ f -- one f -- :+: (f :*: f) -- two f's -- :+: (f :*: f :*: f) -- three f's -- :+: (f :*: f :*: f :*: f) -- four f's -- :+: ... -- etc. ---- -- This is the Free Plus on any Functor f. -- -- Incidentally, if used with a Contravariant f, this is -- instead the free Divise. newtype NonEmptyF f a NonEmptyF :: NonEmpty (f a) -> NonEmptyF f a [runNonEmptyF] :: NonEmptyF f a -> NonEmpty (f a) -- | Treat a NonEmptyF f as a product between an f -- and a ListF f. -- -- nonEmptyProd is the record accessor. pattern ProdNonEmpty :: (f :*: ListF f) a -> NonEmptyF f a -- | A maybe f a. -- -- Can be useful for describing a "an f a that may or may not be -- there". -- -- This is the free structure for a "fail"-like typeclass that would only -- have zero :: f a. newtype MaybeF f a MaybeF :: Maybe (f a) -> MaybeF f a [runMaybeF] :: MaybeF f a -> Maybe (f a) -- | A map of f as, indexed by keys of type k. It can be -- useful for represeting a product of many different values of type -- f a, each "at" a different k location. -- -- Can be considered a combination of EnvT and ListF, in a -- way --- a MapF k f a is like a ListF -- (EnvT k f) a with unique (and ordered) keys. -- -- One use case might be to extend a schema with many "options", indexed -- by some string. -- -- For example, if you had a command line argument parser for a single -- command -- --
-- data Command a ---- -- Then you can represent a command line argument parser for -- multiple named commands with -- --
-- type Commands = MapF String Command ---- -- See NEMapF for a non-empty variant, if you want to enforce that -- your bag has at least one f a. newtype MapF k f a MapF :: Map k (f a) -> MapF k f a [runMapF] :: MapF k f a -> Map k (f a) -- | A non-empty map of f as, indexed by keys of type k. -- It can be useful for represeting a product of many different values of -- type f a, each "at" a different k location, where -- you need to have at least one f a at all times. -- -- Can be considered a combination of EnvT and NonEmptyF, -- in a way --- an NEMapF k f a is like a -- NonEmptyF (EnvT k f) a with unique (and -- ordered) keys. -- -- See MapF for some use cases. newtype NEMapF k f a NEMapF :: NEMap k (f a) -> NEMapF k f a [runNEMapF] :: NEMapF k f a -> NEMap k (f a) -- | The free Applicative for a Functor f. data Ap (f :: Type -> Type) a -- | One or more fs convolved with itself. -- -- Essentially: -- --
-- Ap1 f -- ~ f -- one f -- :+: (f `Day` f) -- two f's -- :+: (f `Day` f `Day` f) -- three f's -- :+: (f `Day` f `Day` f `Day` f) -- four f's -- :+: ... -- etc. ---- -- Useful if you want to promote an f to a situation with "at -- least one f sequenced with itself". -- -- Mostly useful for its HFunctor and Interpret instance, -- along with its relationship with Ap and Day. -- -- This is the free Apply --- Basically a "non-empty" Ap. -- -- The construction here is based on Ap, similar to now -- NonEmpty is built on list. data Ap1 :: (Type -> Type) -> Type -> Type [Ap1] :: f a -> Ap f (a -> b) -> Ap1 f b -- | An Ap1 f is just a Day f (Ap -- f). This bidirectional pattern synonym lets you treat it as such. pattern DayAp1 :: Day f (Ap f) a -> Ap1 f a data Alt (f :: Type -> Type) a -- | A Free f is f enhanced with "sequential -- binding" capabilities. It allows you to sequence multiple fs -- one after the other, and also to determine "what f to -- sequence" based on the result of the computation so far. -- -- Essentially, you can think of this as "giving f a -- Monad instance", with all that that entails (return, -- >>=, etc.). -- -- Lift f into it with inject :: f a -> Free f -- a. When you finally want to "use" it, you can interpret it into -- any monadic context: -- --
-- interpret -- :: Monad g -- => (forall x. f x -> g x) -- -> Free f a -- -> g a ---- -- Structurally, this is equivalent to many "nested" f's. A value of type -- Free f a is either: -- --
a
f a
f (f a)
f (f (f a))
-- Step f a ~ (Natural, f a) -- Step f ~ ((,) Natural) :.: f -- functor composition ---- -- It is the fixed point of infinite applications of :+: (functor -- sums). -- -- Intuitively, in an infinite f :+: f :+: f :+: f ..., you have -- exactly one f somewhere. A Step f a -- has that f, with a Natural giving you "where" the -- f is in the long chain. -- -- Can be useful for using with the Monoidal instance of -- :+:. -- -- interpreting it requires no constraint on the target context. -- -- Note that this type and its instances equivalent to EnvT -- (Sum Natural). data Step f a Step :: Natural -> f a -> Step f a [stepPos] :: Step f a -> Natural [stepVal] :: Step f a -> f a -- | A non-empty map of Natural to f a. Basically, contains -- multiple f as, each at a given Natural index. -- --
-- Steps f a ~ Map Natural (f a) -- Steps f ~ Map Natural :.: f -- functor composition ---- -- It is the fixed point of applications of TheseT. -- -- You can think of this as an infinite sparse array of f as. -- -- Intuitively, in an infinite f `TheseT` f `TheseT` f `TheseT` f -- ..., each of those infinite positions may have an f in -- them. However, because of the at-least-one nature of TheseT, we -- know we have at least one f at one position somewhere. -- -- A Steps f a has potentially many fs, each -- stored at a different Natural position, with the guaruntee that -- at least one f exists. -- -- Can be useful for using with the Monoidal instance of -- TheseT. -- -- interpreting it requires at least an Alt instance in the -- target context, since we have to handle potentially more than one -- f. -- -- This type is essentailly the same as NEMapF (Sum -- Natural) (except with a different Semigroup -- instance). newtype Steps f a Steps :: NEMap Natural (f a) -> Steps f a [getSteps] :: Steps f a -> NEMap Natural (f a) -- | The functor combinator that forgets all structure in the input. -- Ignores the input structure and stores no information. -- -- Acts like the "zero" with respect to functor combinator composition. -- --
-- ComposeT ProxyF f ~ ProxyF -- ComposeT f ProxyF ~ ProxyF ---- -- It can be injected into (losing all information), but it is -- impossible to ever retract or interpret it. -- -- This is essentially ConstF (). data ProxyF f a ProxyF :: ProxyF f a -- | Functor combinator that forgets all structure on the input, and -- instead stores a value of type e. -- -- Like ProxyF, acts like a "zero" with functor combinator -- composition. -- -- It can be injected into (losing all information), but it is -- impossible to ever retract or interpret it. data ConstF e f a ConstF :: e -> ConstF e f a [getConstF] :: ConstF e f a -> e data EnvT e (w :: Type -> Type) a EnvT :: e -> w a -> EnvT e (w :: Type -> Type) a -- | The reader monad transformer, which adds a read-only environment to -- the given monad. -- -- The return function ignores the environment, while -- >>= passes the inherited environment to both -- subcomputations. newtype ReaderT r (m :: Type -> Type) a ReaderT :: (r -> m a) -> ReaderT r (m :: Type -> Type) a [runReaderT] :: ReaderT r (m :: Type -> Type) a -> r -> m a -- | An f a, along with a Bool flag -- --
-- Flagged f a ~ (Bool, f a) -- Flagged f ~ ((,) Bool) :.: f -- functor composition ---- -- Creation with inject or pure uses False as the -- boolean. -- -- You can think of it as an f a that is "flagged" with a -- boolean value, and that value can indicuate whether or not it is -- "pure" (made with inject or pure) as False, or -- "impure" (made from some other source) as True. However, -- False may be always created directly, of course, using the -- constructor. -- -- You can think of it like a Step that is either 0 or 1, as well. -- -- interpreting it requires no constraint on the target context. -- -- This type is equivalent (along with its instances) to: -- -- data Flagged f a Flagged :: Bool -> f a -> Flagged f a [flaggedFlag] :: Flagged f a -> Bool [flaggedVal] :: Flagged f a -> f a -- | The trivial monad transformer, which maps a monad to an equivalent -- monad. newtype IdentityT (f :: k -> Type) (a :: k) IdentityT :: f a -> IdentityT (f :: k -> Type) (a :: k) [runIdentityT] :: IdentityT (f :: k -> Type) (a :: k) -> f a -- | Void2 a b is uninhabited for all a and -- b. data Void2 a b -- | A simple way to inject/reject into any eventual typeclass. -- -- In a way, this is the "ultimate" multi-purpose Interpret -- instance. You can use this to inject an f into a free -- structure of any typeclass. If you want f to have a -- Monad instance, for example, just use -- --
-- inject :: f a -> Final Monad f a ---- -- When you want to eventually interpret out the data, use: -- --
-- interpret :: (f ~> g) -> Final c f a -> g a ---- -- Essentially, Final c is the "free c". Final -- Monad is the free Monad, etc. -- -- Final can theoretically replace Ap, Ap1, -- ListF, NonEmptyF, MaybeF, Free, -- Identity, Coyoneda, and other instances of -- FreeOf, if you don't care about being able to pattern match on -- explicit structure. -- -- However, it cannot replace Interpret instances that are not -- free structures, like Step, Steps, Backwards, -- etc. -- -- Note that this doesn't have instances for all the typeclasses -- you could lift things into; you probably have to define your own if -- you want to use Final c as an instance of -- c (using liftFinal0, liftFinal1, -- liftFinal2 for help). newtype Final c f a Final :: (forall g. c g => (forall x. f x -> g x) -> g a) -> Final c f a [runFinal] :: Final c f a -> forall g. c g => (forall x. f x -> g x) -> g a -- | A typeclass associating a free structure with the typeclass it is free -- on. -- -- This essentially lists instances of Interpret where a "trip" -- through Final will leave it unchanged. -- --
-- fromFree . toFree == id -- toFree . fromFree == id ---- -- This can be useful because Final doesn't have a concrete -- structure that you can pattern match on and inspect, but t -- might. This lets you work on a concrete structure if you desire. class FreeOf c t | t -> c where { -- | What "type" of functor is expected: should be either -- Unconstrained, Functor, Contravariant, or -- Invariant. type family FreeFunctorBy t :: (Type -> Type) -> Constraint; type FreeFunctorBy t = Unconstrained; } fromFree :: FreeOf c t => t f ~> Final c f toFree :: (FreeOf c t, FreeFunctorBy t f) => Final c f ~> t f fromFree :: (FreeOf c t, Interpret t (Final c f)) => t f ~> Final c f toFree :: (FreeOf c t, Inject t, c (t f)) => Final c f ~> t f -- | Composition of monad transformers. newtype ComposeT (f :: Type -> Type -> Type -> Type) (g :: Type -> Type -> Type -> Type) (m :: Type -> Type) a ComposeT :: f (g m) a -> ComposeT (f :: (Type -> Type) -> Type -> Type) (g :: (Type -> Type) -> Type -> Type) (m :: Type -> Type) a [getComposeT] :: ComposeT (f :: (Type -> Type) -> Type -> Type) (g :: (Type -> Type) -> Type -> Type) (m :: Type -> Type) a -> f (g m) a infixr 9 `ComposeT` infixr 9 `ComposeT` -- | The Day convolution of two covariant functors. data Day (f :: Type -> Type) (g :: Type -> Type) a Day :: f b -> g c -> (b -> c -> a) -> Day (f :: Type -> Type) (g :: Type -> Type) a -- | Products: encode multiple arguments to constructors data ( (f :: k -> Type) :*: (g :: k -> Type) ) (p :: k) (:*:) :: f p -> g p -> (:*:) (f :: k -> Type) (g :: k -> Type) (p :: k) infixr 6 :*: infixr 6 :*: -- | outL for :*: actually does not require Functor. -- This is the more general version. prodOutL :: (f :*: g) ~> f -- | outR for :*: actually does not require Functor. -- This is the more general version. prodOutR :: (f :*: g) ~> g -- | Sums: encode choice between constructors data ( (f :: k -> Type) :+: (g :: k -> Type) ) (p :: k) L1 :: f p -> (:+:) (f :: k -> Type) (g :: k -> Type) (p :: k) R1 :: g p -> (:+:) (f :: k -> Type) (g :: k -> Type) (p :: k) infixr 5 :+: -- | Void: used for datatypes without constructors data V1 (p :: k) data These1 (f :: Type -> Type) (g :: Type -> Type) a This1 :: f a -> These1 (f :: Type -> Type) (g :: Type -> Type) a That1 :: g a -> These1 (f :: Type -> Type) (g :: Type -> Type) a These1 :: f a -> g a -> These1 (f :: Type -> Type) (g :: Type -> Type) a -- | Functor composition. Comp f g a is equivalent to f -- (g a), and the Comp pattern synonym is a way of getting -- the f (g a) in a Comp f g a. -- -- For example, Maybe (IO Bool) is -- Comp Maybe IO Bool. -- -- This is mostly useful for its typeclass instances: in particular, -- Functor, Applicative, HBifunctor, and -- Monoidal. -- -- This is essentially a version of :.: and Compose that -- allows for an HBifunctor instance. -- -- It is slightly less performant. Using comp . -- unComp every once in a while will concretize a Comp -- value (if you have Functor f) and remove some -- indirection if you have a lot of chained operations. -- -- The "free monoid" over Comp is Free, and the "free -- semigroup" over Comp is Free1. data Comp f g a -- | Pattern match on and construct a Comp f g a as if it -- were f (g a). pattern Comp :: Functor f => f (g a) -> Comp f g a -- | An HBifunctor that ignores its second input. Like a :+: -- with no R1/right branch. -- -- This is Joker from Data.Bifunctors.Joker, but given a -- more sensible name for its purpose. newtype LeftF f g a LeftF :: f a -> LeftF f g a [runLeftF] :: LeftF f g a -> f a -- | An HBifunctor that ignores its first input. Like a :+: -- with no L1/left branch. -- -- In its polykinded form (on f), it is essentially a -- higher-order version of Tagged. newtype RightF f g a RightF :: g a -> RightF f g a [runRightF] :: RightF f g a -> g a -- | An "HFunctor combinator" that enhances an HFunctor with -- the ability to hold a single f a. This is the higher-order -- analogue of Lift. -- -- You can think of it as a free Inject for any f. -- -- Note that HLift IdentityT is equivalent to -- EnvT Any. data HLift t f a HPure :: f a -> HLift t f a HOther :: t f a -> HLift t f a -- | An "HFunctor combinator" that turns an HFunctor into -- potentially infinite nestings of that HFunctor. -- -- An HFree t f a is either f a, t f a, -- t (t f) a, t (t (t f)) a, etc. -- -- This effectively turns t into a tree with t -- branches. -- -- One particularly useful usage is with MapF. For example if you -- had a data type representing a command line command parser: -- --
-- data Command a ---- -- You could represent "many possible named commands" using -- --
-- type Commands = MapF String Command ---- -- And you can represent multiple nested named commands using: -- --
-- type NestedCommands = HFree (MapF String) ---- -- This has an Interpret instance, but it can be more useful to -- use via direct pattern matching, or through -- --
-- foldHFree -- :: HBifunctor t -- => f ~> g -- -> t g ~> g -- -> HFree t f ~> g ---- -- which requires no extra constriant on g, and lets you -- consider each branch separately. -- -- This can be considered the higher-oder analogue of Free; it is -- the free HBind for any HFunctor t. -- -- Note that HFree IdentityT is equivalent to -- Step. data HFree t f a HReturn :: f a -> HFree t f a HJoin :: t (HFree t f) a -> HFree t f a -- | Turn Identity into any Applicative f. Can be -- useful as an argument to hmap, hbimap, or -- interpret. -- -- It is a more general form of generalize from mmorph. generalize :: Applicative f => Identity ~> f -- | Natural transformation from any functor f into Proxy. -- Can be useful for "zeroing out" a functor with hmap or -- hbimap or interpret. absorb :: f ~> Proxy -- | Convenient helper function to build up a Divisible by providing -- each component of it. This makes it much easier to build up longer -- chains as opposed to nested calls to divide and manually -- peeling off tuples one-by-one. -- -- For example, if you had a data type -- --
-- data MyType = MT Int Bool String ---- -- and a contravariant consumer Builder (representing, say, a -- way to serialize an item, where intBuilder :: Builder Int is -- a serializer of Ints), then you could assemble a serializer a -- MyType using: -- --
-- contramap ((MyType x y z) -> I x :* I y :* I z :* Nil) $ -- divideN $ intBuilderj -- :* boolBuilder -- :* stringBuilder -- :* Nil --divideN :: Divisible f => NP f as -> f (NP I as) -- | A version of divideN that works for non-empty NP, and so -- only requires a Divise constraint. diviseN :: Divise f => NP f (a : as) -> f (NP I (a : as)) -- | Convenient helper function to build up a Conclude by providing -- each component of it. This makes it much easier to build up longer -- chains as opposed to nested calls to decide and manually -- peeling off eithers one-by-one. -- -- For example, if you had a data type -- --
-- data MyType = MTI Int | MTB Bool | MTS String ---- -- and a contravariant consumer Builder (representing, say, a -- way to serialize an item, where intBuilder :: Builder Int is -- a serializer of Ints), then you could assemble a serializer a -- MyType using: -- --
-- contramap (case MTI x -> Z (I x); MTB y -> S (Z (I y)); MTS z -> S (S (Z (I z)))) $ -- concludeN $ intBuilder -- :* boolBuilder -- :* stringBuilder -- :* Nil --concludeN :: Conclude f => NP f as -> f (NS I as) -- | A version of concludeN that works for non-empty -- NP/NS, and so only requires a Decide constraint. decideN :: Decide f => NP f (a : as) -> f (NS I (a : as)) -- | A version of divideN defined to work with XRec, which -- can syntactically cleaner because you don't have to manually -- wrap/unwrap Is. -- -- Using the example for divideN: -- --
-- data MyType = MT Int Bool String -- -- contramap ((MyType x y z) -> x ::& y ::& z ::& Nil) $ -- divideNRec $ intBuilderj -- :& boolBuilder -- :& stringBuilder -- :& RNil --divideNRec :: Divisible f => Rec f as -> f (XRec Identity as) -- | A version of divideNRec that works for non-empty records, and -- so only requires a Divise constraint. diviseNRec :: Divise f => Rec f (a : as) -> f (XRec Identity (a : as))