kernmantle-0.1.0.0: Composing Applicatives, Monads, Comonads and Arrows into Arrows
Safe HaskellNone
LanguageHaskell2010

Control.Kernmantle.Rope

Description

A Rope connects together various effect Strands that get interlaced together.

A Strand is an effet with a parameter and an output. No constraint is placed on the Strand, but once combined in a Rope, that Rope will be an Arrow and a Profunctor. Strands in a Rope are named via labels to limit ambiguity.

An action that targets some Strand can be lifted to a Rope that contains that Strand with the strand function.

Synopsis

Re-exports

newtype Cayley (f :: k -> Type) (p :: k1 -> k2 -> k) (a :: k1) (b :: k2) #

Static arrows. Lifted by Applicative.

Cayley has a polymorphic kind since 5.6.

Constructors

Cayley 

Fields

Instances

Instances details
(Applicative f, Category p) => Category (Cayley f p :: k -> k -> Type) 
Instance details

Defined in Data.Profunctor.Cayley

Methods

id :: forall (a :: k0). Cayley f p a a #

(.) :: forall (b :: k0) (c :: k0) (a :: k0). Cayley f p b c -> Cayley f p a b -> Cayley f p a c #

(Functor f, TryEffect ex eff) => TryEffect ex (Cayley f eff) Source # 
Instance details

Defined in Control.Kernmantle.Error

Methods

tryE :: Cayley f eff a b -> Cayley f eff a (Either ex b) Source #

(Applicative f, ThrowEffect ex eff) => ThrowEffect ex (Cayley f eff) Source # 
Instance details

Defined in Control.Kernmantle.Error

Methods

throwE :: Cayley f eff (Either ex b) b Source #

(SieveTrans f cat, Applicative f') => SieveTrans f (Cayley f' cat) Source # 
Instance details

Defined in Data.Profunctor.Trans

Methods

liftSieve :: (a -> f b) -> Cayley f' cat a b Source #

mapSieve :: ((a -> f b) -> a' -> f b') -> Cayley f' cat a b -> Cayley f' cat a' b' Source #

(HasAutoIdent ai eff, Applicative f) => HasAutoIdent ai (Cayley f eff) Source # 
Instance details

Defined in Control.Kernmantle.Arrow

Methods

liftAutoIdent :: (ArrowIdent -> ai a b) -> Cayley f eff a b Source #

Functor f => ProfunctorFunctor (Cayley f :: (Type -> Type -> Type) -> Type -> Type -> Type) 
Instance details

Defined in Data.Profunctor.Cayley

Methods

promap :: forall (p :: Type -> Type -> Type) (q :: Type -> Type -> Type). Profunctor p => (p :-> q) -> Cayley f p :-> Cayley f q #

(Functor f, Monad f) => ProfunctorMonad (Cayley f :: (Type -> Type -> Type) -> Type -> Type -> Type)

Cayley transforms Monads in Hask into monads on Prof

Instance details

Defined in Data.Profunctor.Cayley

Methods

proreturn :: forall (p :: Type -> Type -> Type). Profunctor p => p :-> Cayley f p #

projoin :: forall (p :: Type -> Type -> Type). Profunctor p => Cayley f (Cayley f p) :-> Cayley f p #

Comonad f => ProfunctorComonad (Cayley f :: (Type -> Type -> Type) -> Type -> Type -> Type)

Cayley transforms Comonads in Hask into comonads on Prof

Instance details

Defined in Data.Profunctor.Cayley

Methods

proextract :: forall (p :: Type -> Type -> Type). Profunctor p => Cayley f p :-> p #

produplicate :: forall (p :: Type -> Type -> Type). Profunctor p => Cayley f p :-> Cayley f (Cayley f p) #

(Applicative f, Arrow p) => Arrow (Cayley f p) 
Instance details

Defined in Data.Profunctor.Cayley

Methods

arr :: (b -> c) -> Cayley f p b c #

first :: Cayley f p b c -> Cayley f p (b, d) (c, d) #

second :: Cayley f p b c -> Cayley f p (d, b) (d, c) #

(***) :: Cayley f p b c -> Cayley f p b' c' -> Cayley f p (b, b') (c, c') #

(&&&) :: Cayley f p b c -> Cayley f p b c' -> Cayley f p b (c, c') #

(Applicative f, ArrowZero p) => ArrowZero (Cayley f p) 
Instance details

Defined in Data.Profunctor.Cayley

Methods

zeroArrow :: Cayley f p b c #

(Applicative f, ArrowPlus p) => ArrowPlus (Cayley f p) 
Instance details

Defined in Data.Profunctor.Cayley

Methods

(<+>) :: Cayley f p b c -> Cayley f p b c -> Cayley f p b c #

(Applicative f, ArrowChoice p) => ArrowChoice (Cayley f p) 
Instance details

Defined in Data.Profunctor.Cayley

Methods

left :: Cayley f p b c -> Cayley f p (Either b d) (Either c d) #

right :: Cayley f p b c -> Cayley f p (Either d b) (Either d c) #

(+++) :: Cayley f p b c -> Cayley f p b' c' -> Cayley f p (Either b b') (Either c c') #

(|||) :: Cayley f p b d -> Cayley f p c d -> Cayley f p (Either b c) d #

(Applicative f, ArrowLoop p) => ArrowLoop (Cayley f p) 
Instance details

Defined in Data.Profunctor.Cayley

Methods

loop :: Cayley f p (b, d) (c, d) -> Cayley f p b c #

(Functor f, Mapping p) => Mapping (Cayley f p) 
Instance details

Defined in Data.Profunctor.Cayley

Methods

map' :: Functor f0 => Cayley f p a b -> Cayley f p (f0 a) (f0 b) #

roam :: ((a -> b) -> s -> t) -> Cayley f p a b -> Cayley f p s t #

(Functor f, Traversing p) => Traversing (Cayley f p) 
Instance details

Defined in Data.Profunctor.Cayley

Methods

traverse' :: Traversable f0 => Cayley f p a b -> Cayley f p (f0 a) (f0 b) #

wander :: (forall (f0 :: Type -> Type). Applicative f0 => (a -> f0 b) -> s -> f0 t) -> Cayley f p a b -> Cayley f p s t #

(Functor f, Choice p) => Choice (Cayley f p) 
Instance details

Defined in Data.Profunctor.Cayley

Methods

left' :: Cayley f p a b -> Cayley f p (Either a c) (Either b c) #

right' :: Cayley f p a b -> Cayley f p (Either c a) (Either c b) #

(Functor f, Cochoice p) => Cochoice (Cayley f p) 
Instance details

Defined in Data.Profunctor.Cayley

Methods

unleft :: Cayley f p (Either a d) (Either b d) -> Cayley f p a b #

unright :: Cayley f p (Either d a) (Either d b) -> Cayley f p a b #

(Functor f, Closed p) => Closed (Cayley f p) 
Instance details

Defined in Data.Profunctor.Cayley

Methods

closed :: Cayley f p a b -> Cayley f p (x -> a) (x -> b) #

(Functor f, Strong p) => Strong (Cayley f p) 
Instance details

Defined in Data.Profunctor.Cayley

Methods

first' :: Cayley f p a b -> Cayley f p (a, c) (b, c) #

second' :: Cayley f p a b -> Cayley f p (c, a) (c, b) #

(Functor f, Costrong p) => Costrong (Cayley f p) 
Instance details

Defined in Data.Profunctor.Cayley

Methods

unfirst :: Cayley f p (a, d) (b, d) -> Cayley f p a b #

unsecond :: Cayley f p (d, a) (d, b) -> Cayley f p a b #

(Functor f, Profunctor p) => Profunctor (Cayley f p) 
Instance details

Defined in Data.Profunctor.Cayley

Methods

dimap :: (a -> b) -> (c -> d) -> Cayley f p b c -> Cayley f p a d #

lmap :: (a -> b) -> Cayley f p b c -> Cayley f p a c #

rmap :: (b -> c) -> Cayley f p a b -> Cayley f p a c #

(#.) :: forall a b c q. Coercible c b => q b c -> Cayley f p a b -> Cayley f p a c #

(.#) :: forall a b c q. Coercible b a => Cayley f p b c -> q a b -> Cayley f p a c #

Rope

data Rope (record :: RopeRec) (mantle :: [Strand]) (core :: BinEff) a b Source #

Rope is a free arrow built out of _several_ binary effects (ie. effects with kind * -> * -> *). These effects are called Strands, they compose the mantle, can be interpreted in an interp effect and can be interlaced "on top" of an existing core effect.

Instances

Instances details
TryEffect ex core => TryEffect ex (Rope record mantle core) Source # 
Instance details

Defined in Control.Kernmantle.Rope

Methods

tryE :: Rope record mantle core a b -> Rope record mantle core a (Either ex b) Source #

ThrowEffect ex core => ThrowEffect ex (Rope record mantle core) Source # 
Instance details

Defined in Control.Kernmantle.Rope

Methods

throwE :: Rope record mantle core (Either ex b) b Source #

SieveTrans f core => SieveTrans f (Rope record mantle core) Source # 
Instance details

Defined in Control.Kernmantle.Rope

Methods

liftSieve :: (a -> f b) -> Rope record mantle core a b Source #

mapSieve :: ((a -> f b) -> a' -> f b') -> Rope record mantle core a b -> Rope record mantle core a' b' Source #

HasAutoIdent eff core => HasAutoIdent eff (Rope record mantle core) Source # 
Instance details

Defined in Control.Kernmantle.Rope

Methods

liftAutoIdent :: (ArrowIdent -> eff a b) -> Rope record mantle core a b Source #

Category core => Category (Rope record mantle core :: Type -> Type -> Type) Source # 
Instance details

Defined in Control.Kernmantle.Rope

Methods

id :: forall (a :: k). Rope record mantle core a a #

(.) :: forall (b :: k) (c :: k) (a :: k). Rope record mantle core b c -> Rope record mantle core a b -> Rope record mantle core a c #

Bifunctor core => Bifunctor (Rope record mantle core) Source # 
Instance details

Defined in Control.Kernmantle.Rope

Methods

bimap :: (a -> b) -> (c -> d) -> Rope record mantle core a c -> Rope record mantle core b d #

first :: (a -> b) -> Rope record mantle core a c -> Rope record mantle core b c #

second :: (b -> c) -> Rope record mantle core a b -> Rope record mantle core a c #

Arrow core => Arrow (Rope record mantle core) Source # 
Instance details

Defined in Control.Kernmantle.Rope

Methods

arr :: (b -> c) -> Rope record mantle core b c #

first :: Rope record mantle core b c -> Rope record mantle core (b, d) (c, d) #

second :: Rope record mantle core b c -> Rope record mantle core (d, b) (d, c) #

(***) :: Rope record mantle core b c -> Rope record mantle core b' c' -> Rope record mantle core (b, b') (c, c') #

(&&&) :: Rope record mantle core b c -> Rope record mantle core b c' -> Rope record mantle core b (c, c') #

ArrowZero core => ArrowZero (Rope record mantle core) Source # 
Instance details

Defined in Control.Kernmantle.Rope

Methods

zeroArrow :: Rope record mantle core b c #

ArrowPlus core => ArrowPlus (Rope record mantle core) Source # 
Instance details

Defined in Control.Kernmantle.Rope

Methods

(<+>) :: Rope record mantle core b c -> Rope record mantle core b c -> Rope record mantle core b c #

ArrowChoice core => ArrowChoice (Rope record mantle core) Source # 
Instance details

Defined in Control.Kernmantle.Rope

Methods

left :: Rope record mantle core b c -> Rope record mantle core (Either b d) (Either c d) #

right :: Rope record mantle core b c -> Rope record mantle core (Either d b) (Either d c) #

(+++) :: Rope record mantle core b c -> Rope record mantle core b' c' -> Rope record mantle core (Either b b') (Either c c') #

(|||) :: Rope record mantle core b d -> Rope record mantle core c d -> Rope record mantle core (Either b c) d #

ArrowLoop core => ArrowLoop (Rope record mantle core) Source # 
Instance details

Defined in Control.Kernmantle.Rope

Methods

loop :: Rope record mantle core (b, d) (c, d) -> Rope record mantle core b c #

Biapplicative core => Biapplicative (Rope record mantle core) Source # 
Instance details

Defined in Control.Kernmantle.Rope

Methods

bipure :: a -> b -> Rope record mantle core a b #

(<<*>>) :: Rope record mantle core (a -> b) (c -> d) -> Rope record mantle core a c -> Rope record mantle core b d #

biliftA2 :: (a -> b -> c) -> (d -> e -> f) -> Rope record mantle core a d -> Rope record mantle core b e -> Rope record mantle core c f #

(*>>) :: Rope record mantle core a b -> Rope record mantle core c d -> Rope record mantle core c d #

(<<*) :: Rope record mantle core a b -> Rope record mantle core c d -> Rope record mantle core a b #

Mapping core => Mapping (Rope record mantle core) Source # 
Instance details

Defined in Control.Kernmantle.Rope

Methods

map' :: Functor f => Rope record mantle core a b -> Rope record mantle core (f a) (f b) #

roam :: ((a -> b) -> s -> t) -> Rope record mantle core a b -> Rope record mantle core s t #

Traversing core => Traversing (Rope record mantle core) Source # 
Instance details

Defined in Control.Kernmantle.Rope

Methods

traverse' :: Traversable f => Rope record mantle core a b -> Rope record mantle core (f a) (f b) #

wander :: (forall (f :: Type -> Type). Applicative f => (a -> f b) -> s -> f t) -> Rope record mantle core a b -> Rope record mantle core s t #

Choice core => Choice (Rope record mantle core) Source # 
Instance details

Defined in Control.Kernmantle.Rope

Methods

left' :: Rope record mantle core a b -> Rope record mantle core (Either a c) (Either b c) #

right' :: Rope record mantle core a b -> Rope record mantle core (Either c a) (Either c b) #

Cochoice core => Cochoice (Rope record mantle core) Source # 
Instance details

Defined in Control.Kernmantle.Rope

Methods

unleft :: Rope record mantle core (Either a d) (Either b d) -> Rope record mantle core a b #

unright :: Rope record mantle core (Either d a) (Either d b) -> Rope record mantle core a b #

Closed core => Closed (Rope record mantle core) Source # 
Instance details

Defined in Control.Kernmantle.Rope

Methods

closed :: Rope record mantle core a b -> Rope record mantle core (x -> a) (x -> b) #

Strong core => Strong (Rope record mantle core) Source # 
Instance details

Defined in Control.Kernmantle.Rope

Methods

first' :: Rope record mantle core a b -> Rope record mantle core (a, c) (b, c) #

second' :: Rope record mantle core a b -> Rope record mantle core (c, a) (c, b) #

Costrong core => Costrong (Rope record mantle core) Source # 
Instance details

Defined in Control.Kernmantle.Rope

Methods

unfirst :: Rope record mantle core (a, d) (b, d) -> Rope record mantle core a b #

unsecond :: Rope record mantle core (d, a) (d, b) -> Rope record mantle core a b #

Profunctor core => Profunctor (Rope record mantle core) Source # 
Instance details

Defined in Control.Kernmantle.Rope

Methods

dimap :: (a -> b) -> (c -> d) -> Rope record mantle core b c -> Rope record mantle core a d #

lmap :: (a -> b) -> Rope record mantle core b c -> Rope record mantle core a c #

rmap :: (b -> c) -> Rope record mantle core a b -> Rope record mantle core a c #

(#.) :: forall a b c q. Coercible c b => q b c -> Rope record mantle core a b -> Rope record mantle core a c #

(.#) :: forall a b c q. Coercible b a => Rope record mantle core b c -> q a b -> Rope record mantle core a c #

type TightRope = Rope ARec Source #

A Rope that is "tight", meaning you cannot weave new Strands to it. The strand function is O(1) on TightRopes whatever the number of Strands.

type LooseRope = Rope Rec Source #

A Rope that is "loose", meaning you can weave new Strands to it. The strand function is O(n) on LooseRopes, n being the number of Strands.

loosen :: NatToInt (RLength m) => TightRope m core :-> LooseRope m core Source #

Turn a TightRope into a LooseRope. This is very often the first step in a chain of weaves.

mapRopeCore :: (core a b -> core a' b') -> Rope r m core a b -> Rope r m core a' b' Source #

Applies a function on the core action of the Rope

mergeStrands :: Label n1 -> Label n2 -> LooseRope ('(n1, binEff) ': ('(n2, binEff) ': mantle)) core :-> LooseRope ('(n1, binEff) ': mantle) core Source #

Merge two strands that have the same effect type. Keeps the first name.

Binary Effects and Strands

type BinEff = * -> * -> * Source #

The kind for all binary effects. First param is usually an input (contravariant) of the effect and second one an output (covariant).

type Strand = (Symbol, BinEff) Source #

The kind for a named binary effect. Must remain a tuple because that's what vinyl expects.

type (:::) (a :: k) (b :: k1) = '(a, b) #

Alias for Field spec

type family StrandName t where ... Source #

Equations

StrandName '(name, eff) = name 

type family StrandEff t where ... Source #

Equations

StrandEff '(name, eff) = eff 

type family InRope l eff rope where ... Source #

Tells that a strand of effects '(l,eff) is present in the rope

Equations

InRope l eff (Rope record mantle core) = (HasField record l mantle mantle eff eff, RecElemFCtx record (Weaver core)) 

type AllInMantle strands mantle core = (NatToInt (RLength mantle), RecApplicative mantle, RPureConstrained (IndexableField mantle) mantle, LooseRope mantle core `Entwines` strands, TightRope mantle core `Entwines` strands) Source #

Useful for functions that want to use tighten/loosen

strand :: InRope l eff (Rope r m c) => Label l -> eff :-> Rope r m c Source #

mapStrand :: InRope l eff (Rope r m c) => Label l -> (eff :-> eff) -> Rope r m c :-> Rope r m c Source #

Rope Interpretation

weave Source #

Arguments

:: forall name binEff mantle core. Label name

The name of the strand to be woven.

-> ((LooseRope ('(name, binEff) ': mantle) core :-> core) -> binEff :-> core)

The interpretation function for the effect, which can depend on the global interpretation function for the rope.

-> LooseRope ('(name, binEff) ': mantle) core :-> LooseRope mantle core

An interpretation function for a Rope with containing the given effect strand, transformed into the same Rope but with that effect woven in the core.

Adds a new effect strand in the Rope by decribing how to interpret that in the core. The interpretation function is fed the fixpoint of all interpretation functions, meaning the interpretation function can itself use effects in the Rope. For example, given an effect Eff, whose label is "effect" being interpreted in a core effect CoreEff, one first defines an interpretation function:

  interpret ::
    (LooseRope '("effect",Eff) ': mantle) core :-> CoreEff) ->
     Eff a b -> CoreEff a b

  interpret ::
    (LooseRope '("effect",Eff) ': mantle) core :-> CoreEff) ->
    (Eff :-> CoreEff)

where p :-> q corresponds to forall a b. p a b -> q a b, and obtain an interpreter for the strand:

  strandInterpreter ::
    LooseRope ('("effect",Eff) ': mantle) CoreEff :->
    LooseRope mantle CoreEff
  strandInterpreter = weave #effect interpret

weave' Source #

Arguments

:: forall name binEff mantle core. Label name

The name of the strand to be woven.

-> (binEff :-> core)

The interpretation function for the effect.

-> LooseRope ('(name, binEff) ': mantle) core :-> LooseRope mantle core

An interpretation function for a Rope with containing the given effect strand, transformed into the same Rope but with that effect woven in the core.

A version of weave where the strand can be directly interpreted in the core with no need to trigger other effects. For example, given an effect Eff, whose label is "effect" being interpreted in a core effect CoreEff, one first defines an interpretation function:

  interpret :: Eff a b -> CoreEff a b
  interpret :: Eff :-> CoreEff

and obtain an interpreter for the strand:

  strandInterpreter ::
    LooseRope ('("effect",Eff) ': mantle) CoreEff :->
    LooseRope mantle CoreEff
  strandInterpreter = weave' #effect interpret

weaveK :: HasKleisli m core => Label name -> (forall a b. binEff a b -> a -> m b) -> LooseRope ('(name, binEff) ': mantle) core :-> LooseRope mantle core Source #

A shortcut for weave' when your core HasKleisli

class WeaveAll mantle core where Source #

Supports weaveAll over any Rope

Methods

weaveAll :: (forall lbl eff. lbl -> eff :-> core) -> LooseRope mantle core :-> core Source #

Weaves all the remaining strands in the core, provided a polymorphic-enough interpretation function can be provided.

This function is notably useful to implement the "Rope-in-Rope" pattern, when a Rope (possibly wrapped in Cayley) is used as the code for another Rope. weaveAll in that case permits to transfer all the effects of the outer Rope to the core Rope.

Instances

Instances details
WeaveAll ('[] :: [Strand]) core Source # 
Instance details

Defined in Control.Kernmantle.Rope

Methods

weaveAll :: (forall lbl (eff :: Type -> Type -> Type). lbl -> eff :-> core) -> LooseRope '[] core :-> core Source #

WeaveAll mantle core => WeaveAll ((name ::: eff) ': mantle) core Source # 
Instance details

Defined in Control.Kernmantle.Rope

Methods

weaveAll :: (forall lbl (eff0 :: Type -> Type -> Type). lbl -> eff0 :-> core) -> LooseRope ((name ::: eff) ': mantle) core :-> core Source #

retwine :: RetwinableAs r strands core strands' => Rope r strands core :-> Rope r strands' core Source #

Reorders the strands to match some external context. strands' can contain more elements than strands. Note it works on both TightRopes and LooseRopes

untwine :: LooseRope '[] core :-> core Source #

Strips a Rope of its empty mantle. Usually the last step of the interpretation of a Rope.

Predicates

type AnyRopeWith strands coreConstraints a b = forall mantle r core. (Rope r mantle core `Entwines` strands, core `SatisfiesAll` coreConstraints) => Rope r mantle core a b Source #

A AnyRopeWith strands costraints is a Rope with contains the strands in the variable strands , and whose core effect obeys the constraints in the contraints variable.

type TightRopeWith strands coreConstraints a b = forall mantle core. (TightRope mantle core `Entwines` strands, core `SatisfiesAll` coreConstraints) => TightRope mantle core a b Source #

type LooseRopeWith strands coreConstraints a b = forall mantle core. (LooseRope mantle core `Entwines` strands, core `SatisfiesAll` coreConstraints) => LooseRope mantle core a b Source #

type family Entwines rope (strands :: [Strand]) :: Constraint where ... Source #

Tells whether a collection of strands is in a Rope.

Equations

Entwines rope '[] = () 
Entwines rope ('(name, eff) ': strands) = (InRope name eff rope, rope `Entwines` strands) 

type family SatisfiesAll (x :: k) (csts :: [k -> Constraint]) :: Constraint where ... Source #

Tells whether a type satisfies all the given constraints.

Equations

SatisfiesAll x '[] = () 
SatisfiesAll x (c1 ': cnsts) = (c1 x, x `SatisfiesAll` cnsts) 

Reexports

type (:->) (p :: k -> k1 -> Type) (q :: k -> k1 -> Type) = forall (a :: k) (b :: k1). p a b -> q a b infixr 0 #

(:->) has a polymorphic kind since 5.6.

data Label (a :: Symbol) #

Proxy for label type

Instances

Instances details
s ~ s' => IsLabel s (Label s') 
Instance details

Defined in Data.Vinyl.Derived

Methods

fromLabel :: Label s' #

Eq (Label a) 
Instance details

Defined in Data.Vinyl.Derived

Methods

(==) :: Label a -> Label a -> Bool #

(/=) :: Label a -> Label a -> Bool #

Show (Label a) 
Instance details

Defined in Data.Vinyl.Derived

Methods

showsPrec :: Int -> Label a -> ShowS #

show :: Label a -> String #

showList :: [Label a] -> ShowS #

fromLabel :: IsLabel x a => a #

(&) :: a -> (a -> b) -> b infixl 1 #

& is a reverse application operator. This provides notational convenience. Its precedence is one higher than that of the forward application operator $, which allows & to be nested in $.

>>> 5 & (+1) & show
"6"

Since: base-4.8.0.0

mkRope :: (record (Weaver core) mantle -> core a b) -> Rope record mantle core a b Source #

runRope :: Rope record mantle core a b -> record (Weaver core) mantle -> core a b Source #