Safe Haskell | None |
---|---|
Language | Haskell2010 |
Synopsis
- type family CanonicalEffect (p :: (Type -> Type) -> Constraint) :: (Type -> Type) -> Type -> Type
- newtype ConstrainedAction (p :: (Type -> Type) -> Constraint) (m :: Type -> Type) (s :: Type) (x :: Type) = ConstrainedAction {
- action :: m x
- class ReifiableConstraint1 p where
- data Dict1 (p :: (Type -> Type) -> Constraint) (m :: Type -> Type)
- reifiedInstance :: Monad m => Reifies s (Dict1 p m) :- p (ConstrainedAction p m s)
- class ReifiableConstraint1 p => IsCanonicalEffect p r where
- canonicalDictionary :: Dict1 p (Sem r)
- absorb :: forall p r a. IsCanonicalEffect p r => (p (Sem r) => Sem r a) -> Sem r a
- absorbReader :: Member (Reader i) r => (MonadReader i (Sem r) => Sem r a) -> Sem r a
- absorbState :: Member (State s) r => (MonadState s (Sem r) => Sem r a) -> Sem r a
- absorbWriter :: (Monoid w, Member (Writer w) r) => (MonadWriter w (Sem r) => Sem r a) -> Sem r a
- absorbError :: forall e r a. Member (Error e) r => (MonadError e (Sem r) => Sem r a) -> Sem r a
- class Reifies (s :: k) a | s -> a
- newtype a :- b = Sub (a -> Dict b)
- data Dict a where
- reflect :: Reifies s a => proxy s -> a
- data Proxy (t :: k) :: forall k. k -> Type = Proxy
Types
type family CanonicalEffect (p :: (Type -> Type) -> Constraint) :: (Type -> Type) -> Type -> Type Source #
Open type-family mapping a single constraint of the form
(Type -> Type) -> Constraint
, e.g., MonadState s
,
to a polysemy effect which can be used to re-interpret
that constraint, e.g., 'State s'.
Instances
type CanonicalEffect (MonadWriter w) Source # | |
Defined in Polysemy.MTL | |
type CanonicalEffect (MonadState s) Source # | |
Defined in Polysemy.MTL | |
type CanonicalEffect (MonadReader env) Source # | |
Defined in Polysemy.MTL | |
type CanonicalEffect (MonadError e) Source # | |
Defined in Polysemy.MTL |
newtype ConstrainedAction (p :: (Type -> Type) -> Constraint) (m :: Type -> Type) (s :: Type) (x :: Type) Source #
A newtype wrapper for a monadic action, parameterized by
a constraint, p
on a (Type -> Type)
(e.g., a monad); m
, a specific
(Type -> Type)
; and a polysemy effect type-list r
. With Data.Reflection
we can create instances of p (ConstrainedAction p m r)
using functions from
Sem r
.
ConstrainedAction | |
|
Instances
class ReifiableConstraint1 p where Source #
For a constraint to be "absorbable" by Sem r
,
there needs to be an instance of this class,
containing the dictionary signatures as a record of functions and the
reflected entailment of p (ConstrainedAction p m r)
from the reified dictionary.
reifiedInstance :: Monad m => Reifies s (Dict1 p m) :- p (ConstrainedAction p m s) Source #
Instances
class ReifiableConstraint1 p => IsCanonicalEffect p r where Source #
This class contains an instance of the dictionary for some set of effects
parameterized by a polysemy effect list r
.
Typically, you would write this instance for any r
satisfying the constraint that the "canonical" effect is a member. But you
could also use it to discharge constraints which require multiple polysemy effects.
canonicalDictionary :: Dict1 p (Sem r) Source #
Instances
Member (RandomFu :: (Type -> Type) -> Type -> Type) r => IsCanonicalEffect MonadRandom r Source # | |
Defined in Polysemy.RandomFu canonicalDictionary :: Dict1 MonadRandom (Sem r) Source # | |
(Monoid w, Member (Writer w) r) => IsCanonicalEffect (MonadWriter w) r Source # | |
Defined in Polysemy.MTL canonicalDictionary :: Dict1 (MonadWriter w) (Sem r) Source # | |
Member (State s :: (Type -> Type) -> Type -> Type) r => IsCanonicalEffect (MonadState s) r Source # | |
Defined in Polysemy.MTL canonicalDictionary :: Dict1 (MonadState s) (Sem r) Source # | |
Member (Reader i) r => IsCanonicalEffect (MonadReader i) r Source # | |
Defined in Polysemy.MTL canonicalDictionary :: Dict1 (MonadReader i) (Sem r) Source # | |
Member (Error e :: (Type -> Type) -> Type -> Type) r => IsCanonicalEffect (MonadError e) r Source # | |
Defined in Polysemy.MTL canonicalDictionary :: Dict1 (MonadError e) (Sem r) Source # |
constraint-polymorphic absorber
absorb :: forall p r a. IsCanonicalEffect p r => (p (Sem r) => Sem r a) -> Sem r a Source #
Given a "canonical" dictionary for p
using the polysemy effects in r
,
discharge the constraint p
.
constraint-monomorphic absorbers
absorbReader :: Member (Reader i) r => (MonadReader i (Sem r) => Sem r a) -> Sem r a Source #
absorbState :: Member (State s) r => (MonadState s (Sem r) => Sem r a) -> Sem r a Source #
absorbWriter :: (Monoid w, Member (Writer w) r) => (MonadWriter w (Sem r) => Sem r a) -> Sem r a Source #
absorbError :: forall e r a. Member (Error e) r => (MonadError e (Sem r) => Sem r a) -> Sem r a Source #
Re-exports
class Reifies (s :: k) a | s -> a #
Instances
KnownNat n => Reifies (n :: Nat) Integer | |
Defined in Data.Reflection | |
KnownSymbol n => Reifies (n :: Symbol) String | |
Defined in Data.Reflection | |
Reifies Z Int | |
Defined in Data.Reflection | |
Reifies n Int => Reifies (D n :: Type) Int | |
Defined in Data.Reflection | |
Reifies n Int => Reifies (SD n :: Type) Int | |
Defined in Data.Reflection | |
Reifies n Int => Reifies (PD n :: Type) Int | |
Defined in Data.Reflection | |
(B b0, B b1, B b2, B b3, B b4, B b5, B b6, B b7, w0 ~ W b0 b1 b2 b3, w1 ~ W b4 b5 b6 b7) => Reifies (Stable w0 w1 a :: Type) a | |
Defined in Data.Reflection |
This is the type of entailment.
a
is read as :-
ba
"entails" b
.
With this we can actually build a category for Constraint
resolution.
e.g.
Because
is a superclass of Eq
a
, we can show that Ord
a
entails Ord
a
.Eq
a
Because instance
exists, we can show that Ord
a => Ord
[a]
entails Ord
a
as well.Ord
[a]
This relationship is captured in the :-
entailment type here.
Since p
and entailment composes, :-
p:-
forms the arrows of a
Category
of constraints. However, Category
only became sufficiently
general to support this instance in GHC 7.8, so prior to 7.8 this instance
is unavailable.
But due to the coherence of instance resolution in Haskell, this Category
has some very interesting properties. Notably, in the absence of
IncoherentInstances
, this category is "thin", which is to say that
between any two objects (constraints) there is at most one distinguishable
arrow.
This means that for instance, even though there are two ways to derive
, the answers from these two paths _must_ by
construction be equal. This is a property that Haskell offers that is
pretty much unique in the space of languages with things they call "type
classes".Ord
a :-
Eq
[a]
What are the two ways?
Well, we can go from
via the
superclass relationship, and then from Ord
a :-
Eq
a
via the
instance, or we can go from Eq
a :-
Eq
[a]
via the instance
then from Ord
a :-
Ord
[a]
through the superclass relationship
and this diagram by definition must "commute".Ord
[a] :-
Eq
[a]
Diagrammatically,
Ord a ins / \ cls v v Ord [a] Eq a cls \ / ins v v Eq [a]
This safety net ensures that pretty much anything you can write with this library is sensible and can't break any assumptions on the behalf of library authors.
Instances
Category (:-) | Possible since GHC 7.8, when |
() :=> (Eq (a :- b)) | |
() :=> (Ord (a :- b)) | |
() :=> (Show (a :- b)) | |
Eq (a :- b) | Assumes |
(Typeable p, Typeable q, p, q) => Data (p :- q) | |
Defined in Data.Constraint gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b) -> (forall g. g -> c g) -> (p :- q) -> c (p :- q) # gunfold :: (forall b r. Data b => c (b -> r) -> c r) -> (forall r. r -> c r) -> Constr -> c (p :- q) # toConstr :: (p :- q) -> Constr # dataTypeOf :: (p :- q) -> DataType # dataCast1 :: Typeable t => (forall d. Data d => c (t d)) -> Maybe (c (p :- q)) # dataCast2 :: Typeable t => (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c (p :- q)) # gmapT :: (forall b. Data b => b -> b) -> (p :- q) -> p :- q # gmapQl :: (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> (p :- q) -> r # gmapQr :: (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> (p :- q) -> r # gmapQ :: (forall d. Data d => d -> u) -> (p :- q) -> [u] # gmapQi :: Int -> (forall d. Data d => d -> u) -> (p :- q) -> u # gmapM :: Monad m => (forall d. Data d => d -> m d) -> (p :- q) -> m (p :- q) # gmapMp :: MonadPlus m => (forall d. Data d => d -> m d) -> (p :- q) -> m (p :- q) # gmapMo :: MonadPlus m => (forall d. Data d => d -> m d) -> (p :- q) -> m (p :- q) # | |
Ord (a :- b) | Assumes |
Defined in Data.Constraint | |
Show (a :- b) | |
a => NFData (a :- b) | |
Defined in Data.Constraint |
Values of type
capture a dictionary for a constraint of type Dict
pp
.
e.g.
Dict
::Dict
(Eq
Int
)
captures a dictionary that proves we have an:
instance Eq
'Int
Pattern matching on the Dict
constructor will bring this instance into scope.
Instances
a :=> (Read (Dict a)) | |
a :=> (Monoid (Dict a)) | |
a :=> (Enum (Dict a)) | |
a :=> (Bounded (Dict a)) | |
() :=> (Eq (Dict a)) | |
() :=> (Ord (Dict a)) | |
() :=> (Show (Dict a)) | |
() :=> (Semigroup (Dict a)) | |
a => Bounded (Dict a) | |
a => Enum (Dict a) | |
Defined in Data.Constraint | |
Eq (Dict a) | |
(Typeable p, p) => Data (Dict p) | |
Defined in Data.Constraint gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b) -> (forall g. g -> c g) -> Dict p -> c (Dict p) # gunfold :: (forall b r. Data b => c (b -> r) -> c r) -> (forall r. r -> c r) -> Constr -> c (Dict p) # toConstr :: Dict p -> Constr # dataTypeOf :: Dict p -> DataType # dataCast1 :: Typeable t => (forall d. Data d => c (t d)) -> Maybe (c (Dict p)) # dataCast2 :: Typeable t => (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c (Dict p)) # gmapT :: (forall b. Data b => b -> b) -> Dict p -> Dict p # gmapQl :: (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Dict p -> r # gmapQr :: (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> Dict p -> r # gmapQ :: (forall d. Data d => d -> u) -> Dict p -> [u] # gmapQi :: Int -> (forall d. Data d => d -> u) -> Dict p -> u # gmapM :: Monad m => (forall d. Data d => d -> m d) -> Dict p -> m (Dict p) # gmapMp :: MonadPlus m => (forall d. Data d => d -> m d) -> Dict p -> m (Dict p) # gmapMo :: MonadPlus m => (forall d. Data d => d -> m d) -> Dict p -> m (Dict p) # | |
Ord (Dict a) | |
a => Read (Dict a) | |
Show (Dict a) | |
Semigroup (Dict a) | |
a => Monoid (Dict a) | |
NFData (Dict c) | |
Defined in Data.Constraint |
reflect :: Reifies s a => proxy s -> a #
Recover a value inside a reify
context, given a proxy for its
reified type.
data Proxy (t :: k) :: forall k. k -> Type #
Proxy
is a type that holds no data, but has a phantom parameter of
arbitrary type (or even kind). Its use is to provide type information, even
though there is no value available of that type (or it may be too costly to
create one).
Historically,
is a safer alternative to the
Proxy
:: Proxy
a'undefined :: a'
idiom.
>>>
Proxy :: Proxy (Void, Int -> Int)
Proxy
Proxy can even hold types of higher kinds,
>>>
Proxy :: Proxy Either
Proxy
>>>
Proxy :: Proxy Functor
Proxy
>>>
Proxy :: Proxy complicatedStructure
Proxy
Instances
Generic1 (Proxy :: k -> Type) | |
Monad (Proxy :: Type -> Type) | Since: base-4.7.0.0 |
Functor (Proxy :: Type -> Type) | Since: base-4.7.0.0 |
Applicative (Proxy :: Type -> Type) | Since: base-4.7.0.0 |
Foldable (Proxy :: Type -> Type) | Since: base-4.7.0.0 |
Defined in Data.Foldable fold :: Monoid m => Proxy m -> m # foldMap :: Monoid m => (a -> m) -> Proxy a -> m # foldr :: (a -> b -> b) -> b -> Proxy a -> b # foldr' :: (a -> b -> b) -> b -> Proxy a -> b # foldl :: (b -> a -> b) -> b -> Proxy a -> b # foldl' :: (b -> a -> b) -> b -> Proxy a -> b # foldr1 :: (a -> a -> a) -> Proxy a -> a # foldl1 :: (a -> a -> a) -> Proxy a -> a # elem :: Eq a => a -> Proxy a -> Bool # maximum :: Ord a => Proxy a -> a # minimum :: Ord a => Proxy a -> a # | |
Traversable (Proxy :: Type -> Type) | Since: base-4.7.0.0 |
MonadPlus (Proxy :: Type -> Type) | Since: base-4.9.0.0 |
Alternative (Proxy :: Type -> Type) | Since: base-4.9.0.0 |
Bounded (Proxy t) | Since: base-4.7.0.0 |
Enum (Proxy s) | Since: base-4.7.0.0 |
Eq (Proxy s) | Since: base-4.7.0.0 |
Ord (Proxy s) | Since: base-4.7.0.0 |
Read (Proxy t) | Since: base-4.7.0.0 |
Show (Proxy s) | Since: base-4.7.0.0 |
Ix (Proxy s) | Since: base-4.7.0.0 |
Generic (Proxy t) | |
Semigroup (Proxy s) | Since: base-4.9.0.0 |
Monoid (Proxy s) | Since: base-4.7.0.0 |
type Rep1 (Proxy :: k -> Type) | Since: base-4.6.0.0 |
type Rep (Proxy t) | Since: base-4.6.0.0 |