Copyright | (c) Justin Le 2019 |
---|---|
License | BSD3 |
Maintainer | justin@jle.im |
Stability | experimental |
Portability | non-portable |
Safe Haskell | None |
Language | Haskell2010 |
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.
Synopsis
- class Inject t => Interpret t f where
- forI :: Interpret t f => t g a -> (g ~> f) -> f a
- getI :: Interpret t (Const b) => (forall x. f x -> b) -> t f a -> b
- collectI :: Interpret t (Const [b]) => (forall x. f x -> b) -> t f a -> [b]
- class (c a, d a) => AndC c d a
- newtype WrapHF t f a = WrapHF {
- unwrapHF :: t f a
Documentation
class Inject t => Interpret t f where Source #
An Interpret
lets us move in and out of the "enhanced" Functor
(t
f
) and the functor it enhances (f
). An instance
means we have Interpret
t ft f a -> f a
.
For example,
is Free
ff
enhanced with monadic structure. We get:
inject
:: f a ->Free
f ainterpret
::Monad
m => (forall x. f x -> m x) ->Free
f a -> m a
inject
will let us use our f
inside the enhanced
.
Free
finterpret
will let us "extract" the f
from a
if
we can give an interpreting function that interprets Free
ff
into some
target Monad
.
We enforce that:
interpret
id .inject
== id -- orretract
.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.
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 interpret
ed out.
interpret :: (g ~> f) -> t g ~> f Source #
Given an "interpeting function" from f
to g
, interpret the f
out of the t f
into a final context g
.
Instances
Apply f => Interpret Ap1 (f :: Type -> Type) Source # | |
Interpret (Reverse :: (k -> Type) -> k -> Type) (f :: k -> Type) Source # | |
Interpret (Backwards :: (k -> Type) -> k -> Type) (f :: k -> Type) Source # | |
Interpret (IdentityT :: (k -> Type) -> k -> Type) (f :: k -> Type) Source # | |
Interpret (Flagged :: (k -> Type) -> k -> Type) (f :: k -> Type) Source # | |
Interpret (Step :: (k -> Type) -> k -> Type) (f :: k -> Type) Source # | |
Interpret t f => Interpret (HFree t :: (k -> Type) -> k -> Type) (f :: k -> Type) Source # | Never uses |
Interpret t f => Interpret (HLift t :: (k -> Type) -> k -> Type) (f :: k -> Type) Source # | Never uses |
c f => Interpret (Final c :: (k -> Type) -> k -> Type) (f :: k -> Type) Source # | |
Interpret (M1 i c :: (k -> Type) -> k -> Type) (f :: k -> Type) Source # | |
Interpret (RightF g :: (k1 -> Type) -> k1 -> Type) (f :: k1 -> Type) Source # | |
Applicative f => Interpret Ap (f :: Type -> Type) Source # | A free |
Applicative f => Interpret Ap (f :: Type -> Type) Source # | A free |
Applicative f => Interpret Ap (f :: Type -> Type) Source # | A free |
Alternative f => Interpret Alt (f :: Type -> Type) Source # | A free |
Functor f => Interpret Coyoneda (f :: Type -> Type) Source # | A free |
Interpret WrappedApplicative (f :: Type -> Type) Source # | |
Defined in Data.HFunctor.Interpret | |
Pointed f => Interpret MaybeApply (f :: Type -> Type) Source # | A free |
Defined in Data.HFunctor.Interpret | |
Pointed f => Interpret Lift (f :: Type -> Type) Source # | A free |
Bind f => Interpret Free1 (f :: Type -> Type) Source # | A free |
Monad f => Interpret Free (f :: Type -> Type) Source # | A free |
Monoid e => Interpret (EnvT e :: (Type -> Type) -> Type -> Type) (f :: Type -> Type) Source # | |
Plus f => Interpret (These1 g :: (Type -> Type) -> Type -> Type) (f :: Type -> Type) Source # | Technically, |
Plus f => Interpret (ListF :: (Type -> Type) -> Type -> Type) (f :: Type -> Type) Source # | A free |
Alt f => Interpret (NonEmptyF :: (Type -> Type) -> Type -> Type) (f :: Type -> Type) Source # | A free |
Plus f => Interpret (MaybeF :: (Type -> Type) -> Type -> Type) (f :: Type -> Type) Source # | Technically, |
Alt f => Interpret (Steps :: (Type -> Type) -> Type -> Type) (f :: Type -> Type) Source # | |
Plus f => Interpret ((:+:) g :: (Type -> Type) -> Type -> Type) (f :: Type -> Type) Source # | Technically, |
Plus g => Interpret ((:*:) g :: (Type -> Type) -> Type -> Type) (f :: Type -> Type) Source # | |
Plus g => Interpret (Product g :: (Type -> Type) -> Type -> Type) (f :: Type -> Type) Source # | |
Plus f => Interpret (Sum g :: (Type -> Type) -> Type -> Type) (f :: Type -> Type) Source # | Technically, |
(Interpret s f, Interpret t f) => Interpret (ComposeT s t :: (Type -> Type) -> Type -> Type) (f :: Type -> Type) Source # | |
MonadReader r f => Interpret (ReaderT r :: (Type -> Type) -> Type -> Type) (f :: Type -> Type) Source # | A free |
(Monoid k, Plus f) => Interpret (MapF k :: (Type -> Type) -> Type -> Type) (f :: Type -> Type) Source # | |
(Monoid k, Alt f) => Interpret (NEMapF k :: (Type -> Type) -> Type -> Type) (f :: Type -> Type) Source # | |
(HBifunctor t, SemigroupIn t f) => Interpret (Chain1 t :: (Type -> Type) -> Type -> Type) (f :: Type -> Type) Source # | |
MonoidIn t i f => Interpret (Chain t i :: (Type -> Type) -> Type -> Type) (f :: Type -> Type) Source # | We can collapse and interpret an |
forI :: Interpret t f => t g a -> (g ~> f) -> f a Source #
A convenient flipped version of interpret
.
Utilities
getI :: Interpret t (Const b) => (forall x. f x -> b) -> t f a -> b Source #
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
, you
may have extra constraints on Interpret
t fb
.
- If
f
is unconstrained, there are no constraints onb
- If
f
must beApply
,b
needs to be an instance ofSemigroup
- If
f
isApplicative
,b
needs to be an instance ofMonoid
For some constraints (like Monad
), this will not be usable.
-- get the length of theMap String
in theStep
.collectI
length :: Step (Map String) Bool -> Int
collectI :: Interpret t (Const [b]) => (forall x. f x -> b) -> t f a -> [b] Source #
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
,
which will be the case if the constraint on the target functor is
Interpret
t (Const
[b])Functor
, Apply
, Applicative
, or unconstrianed.
-- get the lengths of allMap String
s in theAp
.collectI
length :: Ap (Map String) Bool -> [Int]
class (c a, d a) => AndC c d a Source #
A constraint on a
for both c a
and d a
. Requiring
is the same as requiring AndC
Show
Eq
a(
.Show
a, Eq
a)
Instances
(c a, d a) => AndC (c :: k -> Constraint) (d :: k -> Constraint) (a :: k) Source # | |
Defined in Data.HFunctor.Interpret |
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
.
Instances
HFunctor t => HFunctor (WrapHF t :: (k1 -> Type) -> k2 -> Type) Source # | |
HBind t => HBind (WrapHF t :: (k -> Type) -> k -> Type) Source # | |
Inject t => Inject (WrapHF t :: (k -> Type) -> k -> Type) Source # | |
Functor (t f) => Functor (WrapHF t f) Source # | |
Foldable (t f) => Foldable (WrapHF t f) Source # | |
Defined in Data.HFunctor.Interpret fold :: Monoid m => WrapHF t f m -> m # foldMap :: Monoid m => (a -> m) -> WrapHF t f a -> m # foldr :: (a -> b -> b) -> b -> WrapHF t f a -> b # foldr' :: (a -> b -> b) -> b -> WrapHF t f a -> b # foldl :: (b -> a -> b) -> b -> WrapHF t f a -> b # foldl' :: (b -> a -> b) -> b -> WrapHF t f a -> b # foldr1 :: (a -> a -> a) -> WrapHF t f a -> a # foldl1 :: (a -> a -> a) -> WrapHF t f a -> a # toList :: WrapHF t f a -> [a] # null :: WrapHF t f a -> Bool # length :: WrapHF t f a -> Int # elem :: Eq a => a -> WrapHF t f a -> Bool # maximum :: Ord a => WrapHF t f a -> a # minimum :: Ord a => WrapHF t f a -> a # | |
Traversable (t f) => Traversable (WrapHF t f) Source # | |
Defined in Data.HFunctor.Interpret | |
Eq1 (t f) => Eq1 (WrapHF t f) Source # | |
Ord1 (t f) => Ord1 (WrapHF t f) Source # | |
Defined in Data.HFunctor.Interpret | |
Show1 (t f) => Show1 (WrapHF t f) Source # | |
Eq (t f a) => Eq (WrapHF t f a) Source # | |
(Typeable f, Typeable a, Typeable t, Typeable k1, Typeable k2, Data (t f a)) => Data (WrapHF t f a) Source # | |
Defined in Data.HFunctor.Interpret gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b) -> (forall g. g -> c g) -> WrapHF t f a -> c (WrapHF t f a) # gunfold :: (forall b r. Data b => c (b -> r) -> c r) -> (forall r. r -> c r) -> Constr -> c (WrapHF t f a) # toConstr :: WrapHF t f a -> Constr # dataTypeOf :: WrapHF t f a -> DataType # dataCast1 :: Typeable t0 => (forall d. Data d => c (t0 d)) -> Maybe (c (WrapHF t f a)) # dataCast2 :: Typeable t0 => (forall d e. (Data d, Data e) => c (t0 d e)) -> Maybe (c (WrapHF t f a)) # gmapT :: (forall b. Data b => b -> b) -> WrapHF t f a -> WrapHF t f a # gmapQl :: (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> WrapHF t f a -> r # gmapQr :: (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> WrapHF t f a -> r # gmapQ :: (forall d. Data d => d -> u) -> WrapHF t f a -> [u] # gmapQi :: Int -> (forall d. Data d => d -> u) -> WrapHF t f a -> u # gmapM :: Monad m => (forall d. Data d => d -> m d) -> WrapHF t f a -> m (WrapHF t f a) # gmapMp :: MonadPlus m => (forall d. Data d => d -> m d) -> WrapHF t f a -> m (WrapHF t f a) # gmapMo :: MonadPlus m => (forall d. Data d => d -> m d) -> WrapHF t f a -> m (WrapHF t f a) # | |
Ord (t f a) => Ord (WrapHF t f a) Source # | |
Defined in Data.HFunctor.Interpret | |
Read (t f a) => Read (WrapHF t f a) Source # | |
Show (t f a) => Show (WrapHF t f a) Source # | |
Generic (WrapHF t f a) Source # | |
type Rep (WrapHF t f a) Source # | |
Defined in Data.HFunctor.Interpret |