{-# LANGUAGE GADTs #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE OverloadedLabels #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE FunctionalDependencies #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}

-- | A 'Rope' connects together various effect 'Strand's 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'. 'Strand's 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.

module Control.Kernmantle.Rope
  ( -- * Re-exports
    module Data.Profunctor.Trans
  , Cayley (..)
    -- * Rope
  , Rope
  , TightRope
  , LooseRope
  , tighten
  , loosen
  , mapRopeCore
  , mergeStrands
    -- * Binary Effects and Strands
  , BinEff
  , Strand
  , (:::)
  , StrandName
  , StrandEff
  , InRope
  , AllInMantle
  , strand
  , mapStrand
    -- * Rope Interpretation
  , weave, weave', weaveK
  , WeaveAll (..)
  , retwine
  , untwine
    -- * Predicates
  , AnyRopeWith
  , TightRopeWith
  , LooseRopeWith
  , Entwines
  , SatisfiesAll
    -- * Reexports
  , type (:->)
  , Label, fromLabel
  , (&)
  , mkRope
  , runRope
  )
where

import Control.Category
import Control.Arrow
import Data.Bifunctor
import Data.Biapplicative
import Data.Bifunctor.Tannen
import Data.Function ((&))
import Data.Profunctor hiding (rmap)
import Data.Profunctor.Cayley (Cayley (..))
import Data.Profunctor.EffFunctor
import Data.Profunctor.Sieve
import Data.Profunctor.Trans
import Data.Profunctor.Traversing
import Data.Profunctor.Unsafe ((#.))
import Data.Vinyl hiding ((<+>))
import Data.Vinyl.ARec
import Data.Vinyl.Functor
import Data.Vinyl.TypeLevel
import GHC.Exts
import GHC.OverloadedLabels

import Prelude hiding (id, (.))

import Control.Kernmantle.Arrow
import Control.Kernmantle.Error
import Control.Kernmantle.Rope.Internal


-- | 'Rope' is a free arrow built out of _several_ binary effects (ie. effects
-- with kind * -> * -> *). These effects are called 'Strand's, they compose the
-- @mantle@, can be interpreted in an @interp@ effect and can be interlaced "on
-- top" of an existing @core@ effect.
newtype Rope (record::RopeRec) (mantle::[Strand]) (core::BinEff) a b =
  Rope { Rope record mantle core a b
-> RopeRunner record mantle core core a b
getRopeRunner :: RopeRunner record mantle core core a b }

  deriving ( Rope record mantle core a a
Rope record mantle core b c
-> Rope record mantle core a b -> Rope record mantle core a c
(forall a. Rope record mantle core a a)
-> (forall b c a.
    Rope record mantle core b c
    -> Rope record mantle core a b -> Rope record mantle core a c)
-> Category (Rope record mantle core)
forall a. Rope record mantle core a a
forall b c a.
Rope record mantle core b c
-> Rope record mantle core a b -> Rope record mantle core a c
forall k (cat :: k -> k -> *).
(forall (a :: k). cat a a)
-> (forall (b :: k) (c :: k) (a :: k).
    cat b c -> cat a b -> cat a c)
-> Category cat
forall (record :: RopeRec) (mantle :: [Strand]) (core :: BinEff) a.
Category core =>
Rope record mantle core a a
forall (record :: RopeRec) (mantle :: [Strand]) (core :: BinEff) b
       c a.
Category core =>
Rope record mantle core b c
-> Rope record mantle core a b -> Rope record mantle core a c
. :: Rope record mantle core b c
-> Rope record mantle core a b -> Rope record mantle core a c
$c. :: forall (record :: RopeRec) (mantle :: [Strand]) (core :: BinEff) b
       c a.
Category core =>
Rope record mantle core b c
-> Rope record mantle core a b -> Rope record mantle core a c
id :: Rope record mantle core a a
$cid :: forall (record :: RopeRec) (mantle :: [Strand]) (core :: BinEff) a.
Category core =>
Rope record mantle core a a
Category
           , Category (Rope record mantle core)
Category (Rope record mantle core)
-> (forall b c. (b -> c) -> Rope record mantle core b c)
-> (forall b c d.
    Rope record mantle core b c
    -> Rope record mantle core (b, d) (c, d))
-> (forall b c d.
    Rope record mantle core b c
    -> Rope record mantle core (d, b) (d, c))
-> (forall b c b' c'.
    Rope record mantle core b c
    -> Rope record mantle core b' c'
    -> Rope record mantle core (b, b') (c, c'))
-> (forall b c c'.
    Rope record mantle core b c
    -> Rope record mantle core b c'
    -> Rope record mantle core b (c, c'))
-> Arrow (Rope record mantle core)
Rope record mantle core b c
-> Rope record mantle core (b, d) (c, d)
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')
(b -> c) -> Rope record mantle core b c
forall b c. (b -> c) -> Rope record mantle core b c
forall b c d.
Rope record mantle core b c
-> Rope record mantle core (b, d) (c, d)
forall b c d.
Rope record mantle core b c
-> Rope record mantle core (d, b) (d, c)
forall b c c'.
Rope record mantle core b c
-> Rope record mantle core b c'
-> Rope record mantle core b (c, c')
forall b c b' c'.
Rope record mantle core b c
-> Rope record mantle core b' c'
-> Rope record mantle core (b, b') (c, c')
forall (a :: BinEff).
Category a
-> (forall b c. (b -> c) -> a b c)
-> (forall b c d. a b c -> a (b, d) (c, d))
-> (forall b c d. a b c -> a (d, b) (d, c))
-> (forall b c b' c'. a b c -> a b' c' -> a (b, b') (c, c'))
-> (forall b c c'. a b c -> a b c' -> a b (c, c'))
-> Arrow a
forall (record :: RopeRec) (mantle :: [Strand]) (core :: BinEff).
Arrow core =>
Category (Rope record mantle core)
forall (record :: RopeRec) (mantle :: [Strand]) (core :: BinEff) b
       c.
Arrow core =>
(b -> c) -> Rope record mantle core b c
forall (record :: RopeRec) (mantle :: [Strand]) (core :: BinEff) b
       c d.
Arrow core =>
Rope record mantle core b c
-> Rope record mantle core (b, d) (c, d)
forall (record :: RopeRec) (mantle :: [Strand]) (core :: BinEff) b
       c d.
Arrow core =>
Rope record mantle core b c
-> Rope record mantle core (d, b) (d, c)
forall (record :: RopeRec) (mantle :: [Strand]) (core :: BinEff) b
       c c'.
Arrow core =>
Rope record mantle core b c
-> Rope record mantle core b c'
-> Rope record mantle core b (c, c')
forall (record :: RopeRec) (mantle :: [Strand]) (core :: BinEff) b
       c b' c'.
Arrow core =>
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')
$c&&& :: forall (record :: RopeRec) (mantle :: [Strand]) (core :: BinEff) b
       c c'.
Arrow core =>
Rope record mantle core b c
-> Rope record mantle core b c'
-> Rope record mantle core b (c, c')
*** :: Rope record mantle core b c
-> Rope record mantle core b' c'
-> Rope record mantle core (b, b') (c, c')
$c*** :: forall (record :: RopeRec) (mantle :: [Strand]) (core :: BinEff) b
       c b' c'.
Arrow core =>
Rope record mantle core b c
-> Rope record mantle core b' c'
-> Rope record mantle core (b, b') (c, c')
second :: Rope record mantle core b c
-> Rope record mantle core (d, b) (d, c)
$csecond :: forall (record :: RopeRec) (mantle :: [Strand]) (core :: BinEff) b
       c d.
Arrow core =>
Rope record mantle core b c
-> Rope record mantle core (d, b) (d, c)
first :: Rope record mantle core b c
-> Rope record mantle core (b, d) (c, d)
$cfirst :: forall (record :: RopeRec) (mantle :: [Strand]) (core :: BinEff) b
       c d.
Arrow core =>
Rope record mantle core b c
-> Rope record mantle core (b, d) (c, d)
arr :: (b -> c) -> Rope record mantle core b c
$carr :: forall (record :: RopeRec) (mantle :: [Strand]) (core :: BinEff) b
       c.
Arrow core =>
(b -> c) -> Rope record mantle core b c
$cp1Arrow :: forall (record :: RopeRec) (mantle :: [Strand]) (core :: BinEff).
Arrow core =>
Category (Rope record mantle core)
Arrow, Arrow (Rope record mantle core)
Arrow (Rope record mantle core)
-> (forall b c d.
    Rope record mantle core b c
    -> Rope record mantle core (Either b d) (Either c d))
-> (forall b c d.
    Rope record mantle core b c
    -> Rope record mantle core (Either d b) (Either d c))
-> (forall b c b' c'.
    Rope record mantle core b c
    -> Rope record mantle core b' c'
    -> Rope record mantle core (Either b b') (Either c c'))
-> (forall b d c.
    Rope record mantle core b d
    -> Rope record mantle core c d
    -> Rope record mantle core (Either b c) d)
-> ArrowChoice (Rope record mantle core)
Rope record mantle core b c
-> Rope record mantle core (Either b d) (Either c d)
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
forall b c d.
Rope record mantle core b c
-> Rope record mantle core (Either b d) (Either c d)
forall b c d.
Rope record mantle core b c
-> Rope record mantle core (Either d b) (Either d c)
forall b d c.
Rope record mantle core b d
-> Rope record mantle core c d
-> Rope record mantle core (Either b c) d
forall b c b' c'.
Rope record mantle core b c
-> Rope record mantle core b' c'
-> Rope record mantle core (Either b b') (Either c c')
forall (a :: BinEff).
Arrow a
-> (forall b c d. a b c -> a (Either b d) (Either c d))
-> (forall b c d. a b c -> a (Either d b) (Either d c))
-> (forall b c b' c'.
    a b c -> a b' c' -> a (Either b b') (Either c c'))
-> (forall b d c. a b d -> a c d -> a (Either b c) d)
-> ArrowChoice a
forall (record :: RopeRec) (mantle :: [Strand]) (core :: BinEff).
ArrowChoice core =>
Arrow (Rope record mantle core)
forall (record :: RopeRec) (mantle :: [Strand]) (core :: BinEff) b
       c d.
ArrowChoice core =>
Rope record mantle core b c
-> Rope record mantle core (Either b d) (Either c d)
forall (record :: RopeRec) (mantle :: [Strand]) (core :: BinEff) b
       c d.
ArrowChoice core =>
Rope record mantle core b c
-> Rope record mantle core (Either d b) (Either d c)
forall (record :: RopeRec) (mantle :: [Strand]) (core :: BinEff) b
       d c.
ArrowChoice core =>
Rope record mantle core b d
-> Rope record mantle core c d
-> Rope record mantle core (Either b c) d
forall (record :: RopeRec) (mantle :: [Strand]) (core :: BinEff) b
       c b' c'.
ArrowChoice core =>
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
$c||| :: forall (record :: RopeRec) (mantle :: [Strand]) (core :: BinEff) b
       d c.
ArrowChoice core =>
Rope record mantle core b d
-> Rope record mantle core c d
-> Rope record mantle core (Either b c) d
+++ :: Rope record mantle core b c
-> Rope record mantle core b' c'
-> Rope record mantle core (Either b b') (Either c c')
$c+++ :: forall (record :: RopeRec) (mantle :: [Strand]) (core :: BinEff) b
       c b' c'.
ArrowChoice core =>
Rope record mantle core b c
-> Rope record mantle core b' c'
-> Rope record mantle core (Either b b') (Either c c')
right :: Rope record mantle core b c
-> Rope record mantle core (Either d b) (Either d c)
$cright :: forall (record :: RopeRec) (mantle :: [Strand]) (core :: BinEff) b
       c d.
ArrowChoice core =>
Rope record mantle core b c
-> Rope record mantle core (Either d b) (Either d c)
left :: Rope record mantle core b c
-> Rope record mantle core (Either b d) (Either c d)
$cleft :: forall (record :: RopeRec) (mantle :: [Strand]) (core :: BinEff) b
       c d.
ArrowChoice core =>
Rope record mantle core b c
-> Rope record mantle core (Either b d) (Either c d)
$cp1ArrowChoice :: forall (record :: RopeRec) (mantle :: [Strand]) (core :: BinEff).
ArrowChoice core =>
Arrow (Rope record mantle core)
ArrowChoice, Arrow (Rope record mantle core)
Arrow (Rope record mantle core)
-> (forall b d c.
    Rope record mantle core (b, d) (c, d)
    -> Rope record mantle core b c)
-> ArrowLoop (Rope record mantle core)
Rope record mantle core (b, d) (c, d)
-> Rope record mantle core b c
forall b d c.
Rope record mantle core (b, d) (c, d)
-> Rope record mantle core b c
forall (a :: BinEff).
Arrow a -> (forall b d c. a (b, d) (c, d) -> a b c) -> ArrowLoop a
forall (record :: RopeRec) (mantle :: [Strand]) (core :: BinEff).
ArrowLoop core =>
Arrow (Rope record mantle core)
forall (record :: RopeRec) (mantle :: [Strand]) (core :: BinEff) b
       d c.
ArrowLoop core =>
Rope record mantle core (b, d) (c, d)
-> Rope record mantle core b c
loop :: Rope record mantle core (b, d) (c, d)
-> Rope record mantle core b c
$cloop :: forall (record :: RopeRec) (mantle :: [Strand]) (core :: BinEff) b
       d c.
ArrowLoop core =>
Rope record mantle core (b, d) (c, d)
-> Rope record mantle core b c
$cp1ArrowLoop :: forall (record :: RopeRec) (mantle :: [Strand]) (core :: BinEff).
ArrowLoop core =>
Arrow (Rope record mantle core)
ArrowLoop, Arrow (Rope record mantle core)
Rope record mantle core b c
Arrow (Rope record mantle core)
-> (forall b c. Rope record mantle core b c)
-> ArrowZero (Rope record mantle core)
forall b c. Rope record mantle core b c
forall (a :: BinEff). Arrow a -> (forall b c. a b c) -> ArrowZero a
forall (record :: RopeRec) (mantle :: [Strand]) (core :: BinEff).
ArrowZero core =>
Arrow (Rope record mantle core)
forall (record :: RopeRec) (mantle :: [Strand]) (core :: BinEff) b
       c.
ArrowZero core =>
Rope record mantle core b c
zeroArrow :: Rope record mantle core b c
$czeroArrow :: forall (record :: RopeRec) (mantle :: [Strand]) (core :: BinEff) b
       c.
ArrowZero core =>
Rope record mantle core b c
$cp1ArrowZero :: forall (record :: RopeRec) (mantle :: [Strand]) (core :: BinEff).
ArrowZero core =>
Arrow (Rope record mantle core)
ArrowZero, ArrowZero (Rope record mantle core)
ArrowZero (Rope record mantle core)
-> (forall b c.
    Rope record mantle core b c
    -> Rope record mantle core b c -> Rope record mantle core b c)
-> ArrowPlus (Rope record mantle core)
Rope record mantle core b c
-> Rope record mantle core b c -> Rope record mantle core b c
forall b c.
Rope record mantle core b c
-> Rope record mantle core b c -> Rope record mantle core b c
forall (a :: BinEff).
ArrowZero a -> (forall b c. a b c -> a b c -> a b c) -> ArrowPlus a
forall (record :: RopeRec) (mantle :: [Strand]) (core :: BinEff).
ArrowPlus core =>
ArrowZero (Rope record mantle core)
forall (record :: RopeRec) (mantle :: [Strand]) (core :: BinEff) b
       c.
ArrowPlus core =>
Rope record mantle core b c
-> Rope record mantle core b c -> Rope record mantle core b c
<+> :: Rope record mantle core b c
-> Rope record mantle core b c -> Rope record mantle core b c
$c<+> :: forall (record :: RopeRec) (mantle :: [Strand]) (core :: BinEff) b
       c.
ArrowPlus core =>
Rope record mantle core b c
-> Rope record mantle core b c -> Rope record mantle core b c
$cp1ArrowPlus :: forall (record :: RopeRec) (mantle :: [Strand]) (core :: BinEff).
ArrowPlus core =>
ArrowZero (Rope record mantle core)
ArrowPlus
           , q b c -> Rope record mantle core a b -> Rope record mantle core a c
Rope record mantle core b c -> q a b -> Rope record mantle core a c
(a -> b)
-> (c -> d)
-> Rope record mantle core b c
-> Rope record mantle core a d
(a -> b)
-> Rope record mantle core b c -> Rope record mantle core a c
(b -> c)
-> Rope record mantle core a b -> Rope record mantle core a c
(forall a b c d.
 (a -> b)
 -> (c -> d)
 -> Rope record mantle core b c
 -> Rope record mantle core a d)
-> (forall a b c.
    (a -> b)
    -> Rope record mantle core b c -> Rope record mantle core a c)
-> (forall b c a.
    (b -> c)
    -> Rope record mantle core a b -> Rope record mantle core a c)
-> (forall a b c (q :: BinEff).
    Coercible c b =>
    q b c
    -> Rope record mantle core a b -> Rope record mantle core a c)
-> (forall a b c (q :: BinEff).
    Coercible b a =>
    Rope record mantle core b c
    -> q a b -> Rope record mantle core a c)
-> Profunctor (Rope record mantle core)
forall a b c.
(a -> b)
-> Rope record mantle core b c -> Rope record mantle core a c
forall b c a.
(b -> c)
-> Rope record mantle core a b -> Rope record mantle core a c
forall a b c d.
(a -> b)
-> (c -> d)
-> Rope record mantle core b c
-> Rope record mantle core a d
forall a b c (q :: BinEff).
Coercible b a =>
Rope record mantle core b c -> q a b -> Rope record mantle core a c
forall a b c (q :: BinEff).
Coercible c b =>
q b c -> Rope record mantle core a b -> Rope record mantle core a c
forall (p :: BinEff).
(forall a b c d. (a -> b) -> (c -> d) -> p b c -> p a d)
-> (forall a b c. (a -> b) -> p b c -> p a c)
-> (forall b c a. (b -> c) -> p a b -> p a c)
-> (forall a b c (q :: BinEff).
    Coercible c b =>
    q b c -> p a b -> p a c)
-> (forall a b c (q :: BinEff).
    Coercible b a =>
    p b c -> q a b -> p a c)
-> Profunctor p
forall (record :: RopeRec) (mantle :: [Strand]) (core :: BinEff) a
       b c.
Profunctor core =>
(a -> b)
-> Rope record mantle core b c -> Rope record mantle core a c
forall (record :: RopeRec) (mantle :: [Strand]) (core :: BinEff) b
       c a.
Profunctor core =>
(b -> c)
-> Rope record mantle core a b -> Rope record mantle core a c
forall (record :: RopeRec) (mantle :: [Strand]) (core :: BinEff) a
       b c d.
Profunctor core =>
(a -> b)
-> (c -> d)
-> Rope record mantle core b c
-> Rope record mantle core a d
forall (record :: RopeRec) (mantle :: [Strand]) (core :: BinEff) a
       b c (q :: BinEff).
(Profunctor core, Coercible b a) =>
Rope record mantle core b c -> q a b -> Rope record mantle core a c
forall (record :: RopeRec) (mantle :: [Strand]) (core :: BinEff) a
       b c (q :: BinEff).
(Profunctor core, Coercible c b) =>
q b c -> Rope record mantle core a b -> Rope record mantle core a c
.# :: Rope record mantle core b c -> q a b -> Rope record mantle core a c
$c.# :: forall (record :: RopeRec) (mantle :: [Strand]) (core :: BinEff) a
       b c (q :: BinEff).
(Profunctor core, Coercible b a) =>
Rope record mantle core b c -> q a b -> Rope record mantle core a c
#. :: q b c -> Rope record mantle core a b -> Rope record mantle core a c
$c#. :: forall (record :: RopeRec) (mantle :: [Strand]) (core :: BinEff) a
       b c (q :: BinEff).
(Profunctor core, Coercible c b) =>
q b c -> Rope record mantle core a b -> Rope record mantle core a c
rmap :: (b -> c)
-> Rope record mantle core a b -> Rope record mantle core a c
$crmap :: forall (record :: RopeRec) (mantle :: [Strand]) (core :: BinEff) b
       c a.
Profunctor core =>
(b -> c)
-> Rope record mantle core a b -> Rope record mantle core a c
lmap :: (a -> b)
-> Rope record mantle core b c -> Rope record mantle core a c
$clmap :: forall (record :: RopeRec) (mantle :: [Strand]) (core :: BinEff) a
       b c.
Profunctor core =>
(a -> b)
-> Rope record mantle core b c -> Rope record mantle core a c
dimap :: (a -> b)
-> (c -> d)
-> Rope record mantle core b c
-> Rope record mantle core a d
$cdimap :: forall (record :: RopeRec) (mantle :: [Strand]) (core :: BinEff) a
       b c d.
Profunctor core =>
(a -> b)
-> (c -> d)
-> Rope record mantle core b c
-> Rope record mantle core a d
Profunctor, Profunctor (Rope record mantle core)
Profunctor (Rope record mantle core)
-> (forall a b c.
    Rope record mantle core a b
    -> Rope record mantle core (a, c) (b, c))
-> (forall a b c.
    Rope record mantle core a b
    -> Rope record mantle core (c, a) (c, b))
-> Strong (Rope record mantle core)
Rope record mantle core a b
-> Rope record mantle core (a, c) (b, c)
Rope record mantle core a b
-> Rope record mantle core (c, a) (c, b)
forall a b c.
Rope record mantle core a b
-> Rope record mantle core (a, c) (b, c)
forall a b c.
Rope record mantle core a b
-> Rope record mantle core (c, a) (c, b)
forall (p :: BinEff).
Profunctor p
-> (forall a b c. p a b -> p (a, c) (b, c))
-> (forall a b c. p a b -> p (c, a) (c, b))
-> Strong p
forall (record :: RopeRec) (mantle :: [Strand]) (core :: BinEff).
Strong core =>
Profunctor (Rope record mantle core)
forall (record :: RopeRec) (mantle :: [Strand]) (core :: BinEff) a
       b c.
Strong core =>
Rope record mantle core a b
-> Rope record mantle core (a, c) (b, c)
forall (record :: RopeRec) (mantle :: [Strand]) (core :: BinEff) a
       b c.
Strong core =>
Rope record mantle core a b
-> Rope record mantle core (c, a) (c, b)
second' :: Rope record mantle core a b
-> Rope record mantle core (c, a) (c, b)
$csecond' :: forall (record :: RopeRec) (mantle :: [Strand]) (core :: BinEff) a
       b c.
Strong core =>
Rope record mantle core a b
-> Rope record mantle core (c, a) (c, b)
first' :: Rope record mantle core a b
-> Rope record mantle core (a, c) (b, c)
$cfirst' :: forall (record :: RopeRec) (mantle :: [Strand]) (core :: BinEff) a
       b c.
Strong core =>
Rope record mantle core a b
-> Rope record mantle core (a, c) (b, c)
$cp1Strong :: forall (record :: RopeRec) (mantle :: [Strand]) (core :: BinEff).
Strong core =>
Profunctor (Rope record mantle core)
Strong, Profunctor (Rope record mantle core)
Profunctor (Rope record mantle core)
-> (forall a b c.
    Rope record mantle core a b
    -> Rope record mantle core (Either a c) (Either b c))
-> (forall a b c.
    Rope record mantle core a b
    -> Rope record mantle core (Either c a) (Either c b))
-> Choice (Rope record mantle core)
Rope record mantle core a b
-> Rope record mantle core (Either a c) (Either b c)
Rope record mantle core a b
-> Rope record mantle core (Either c a) (Either c b)
forall a b c.
Rope record mantle core a b
-> Rope record mantle core (Either a c) (Either b c)
forall a b c.
Rope record mantle core a b
-> Rope record mantle core (Either c a) (Either c b)
forall (p :: BinEff).
Profunctor p
-> (forall a b c. p a b -> p (Either a c) (Either b c))
-> (forall a b c. p a b -> p (Either c a) (Either c b))
-> Choice p
forall (record :: RopeRec) (mantle :: [Strand]) (core :: BinEff).
Choice core =>
Profunctor (Rope record mantle core)
forall (record :: RopeRec) (mantle :: [Strand]) (core :: BinEff) a
       b c.
Choice core =>
Rope record mantle core a b
-> Rope record mantle core (Either a c) (Either b c)
forall (record :: RopeRec) (mantle :: [Strand]) (core :: BinEff) a
       b c.
Choice core =>
Rope record mantle core a b
-> Rope record mantle core (Either c a) (Either c b)
right' :: Rope record mantle core a b
-> Rope record mantle core (Either c a) (Either c b)
$cright' :: forall (record :: RopeRec) (mantle :: [Strand]) (core :: BinEff) a
       b c.
Choice core =>
Rope record mantle core a b
-> Rope record mantle core (Either c a) (Either c b)
left' :: Rope record mantle core a b
-> Rope record mantle core (Either a c) (Either b c)
$cleft' :: forall (record :: RopeRec) (mantle :: [Strand]) (core :: BinEff) a
       b c.
Choice core =>
Rope record mantle core a b
-> Rope record mantle core (Either a c) (Either b c)
$cp1Choice :: forall (record :: RopeRec) (mantle :: [Strand]) (core :: BinEff).
Choice core =>
Profunctor (Rope record mantle core)
Choice, Profunctor (Rope record mantle core)
Profunctor (Rope record mantle core)
-> (forall a b x.
    Rope record mantle core a b
    -> Rope record mantle core (x -> a) (x -> b))
-> Closed (Rope record mantle core)
Rope record mantle core a b
-> Rope record mantle core (x -> a) (x -> b)
forall a b x.
Rope record mantle core a b
-> Rope record mantle core (x -> a) (x -> b)
forall (p :: BinEff).
Profunctor p
-> (forall a b x. p a b -> p (x -> a) (x -> b)) -> Closed p
forall (record :: RopeRec) (mantle :: [Strand]) (core :: BinEff).
Closed core =>
Profunctor (Rope record mantle core)
forall (record :: RopeRec) (mantle :: [Strand]) (core :: BinEff) a
       b x.
Closed core =>
Rope record mantle core a b
-> Rope record mantle core (x -> a) (x -> b)
closed :: Rope record mantle core a b
-> Rope record mantle core (x -> a) (x -> b)
$cclosed :: forall (record :: RopeRec) (mantle :: [Strand]) (core :: BinEff) a
       b x.
Closed core =>
Rope record mantle core a b
-> Rope record mantle core (x -> a) (x -> b)
$cp1Closed :: forall (record :: RopeRec) (mantle :: [Strand]) (core :: BinEff).
Closed core =>
Profunctor (Rope record mantle core)
Closed, Profunctor (Rope record mantle core)
Profunctor (Rope record mantle core)
-> (forall a d b.
    Rope record mantle core (a, d) (b, d)
    -> Rope record mantle core a b)
-> (forall d a b.
    Rope record mantle core (d, a) (d, b)
    -> Rope record mantle core a b)
-> Costrong (Rope record mantle core)
Rope record mantle core (a, d) (b, d)
-> Rope record mantle core a b
Rope record mantle core (d, a) (d, b)
-> Rope record mantle core a b
forall d a b.
Rope record mantle core (d, a) (d, b)
-> Rope record mantle core a b
forall a d b.
Rope record mantle core (a, d) (b, d)
-> Rope record mantle core a b
forall (p :: BinEff).
Profunctor p
-> (forall a d b. p (a, d) (b, d) -> p a b)
-> (forall d a b. p (d, a) (d, b) -> p a b)
-> Costrong p
forall (record :: RopeRec) (mantle :: [Strand]) (core :: BinEff).
Costrong core =>
Profunctor (Rope record mantle core)
forall (record :: RopeRec) (mantle :: [Strand]) (core :: BinEff) d
       a b.
Costrong core =>
Rope record mantle core (d, a) (d, b)
-> Rope record mantle core a b
forall (record :: RopeRec) (mantle :: [Strand]) (core :: BinEff) a
       d b.
Costrong core =>
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
$cunsecond :: forall (record :: RopeRec) (mantle :: [Strand]) (core :: BinEff) d
       a b.
Costrong core =>
Rope record mantle core (d, a) (d, b)
-> Rope record mantle core a b
unfirst :: Rope record mantle core (a, d) (b, d)
-> Rope record mantle core a b
$cunfirst :: forall (record :: RopeRec) (mantle :: [Strand]) (core :: BinEff) a
       d b.
Costrong core =>
Rope record mantle core (a, d) (b, d)
-> Rope record mantle core a b
$cp1Costrong :: forall (record :: RopeRec) (mantle :: [Strand]) (core :: BinEff).
Costrong core =>
Profunctor (Rope record mantle core)
Costrong, Profunctor (Rope record mantle core)
Profunctor (Rope record mantle core)
-> (forall a d b.
    Rope record mantle core (Either a d) (Either b d)
    -> Rope record mantle core a b)
-> (forall d a b.
    Rope record mantle core (Either d a) (Either d b)
    -> Rope record mantle core a b)
-> Cochoice (Rope record mantle core)
Rope record mantle core (Either a d) (Either b d)
-> Rope record mantle core a b
Rope record mantle core (Either d a) (Either d b)
-> Rope record mantle core a b
forall d a b.
Rope record mantle core (Either d a) (Either d b)
-> Rope record mantle core a b
forall a d b.
Rope record mantle core (Either a d) (Either b d)
-> Rope record mantle core a b
forall (p :: BinEff).
Profunctor p
-> (forall a d b. p (Either a d) (Either b d) -> p a b)
-> (forall d a b. p (Either d a) (Either d b) -> p a b)
-> Cochoice p
forall (record :: RopeRec) (mantle :: [Strand]) (core :: BinEff).
Cochoice core =>
Profunctor (Rope record mantle core)
forall (record :: RopeRec) (mantle :: [Strand]) (core :: BinEff) d
       a b.
Cochoice core =>
Rope record mantle core (Either d a) (Either d b)
-> Rope record mantle core a b
forall (record :: RopeRec) (mantle :: [Strand]) (core :: BinEff) a
       d b.
Cochoice core =>
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
$cunright :: forall (record :: RopeRec) (mantle :: [Strand]) (core :: BinEff) d
       a b.
Cochoice core =>
Rope record mantle core (Either d a) (Either d b)
-> Rope record mantle core a b
unleft :: Rope record mantle core (Either a d) (Either b d)
-> Rope record mantle core a b
$cunleft :: forall (record :: RopeRec) (mantle :: [Strand]) (core :: BinEff) a
       d b.
Cochoice core =>
Rope record mantle core (Either a d) (Either b d)
-> Rope record mantle core a b
$cp1Cochoice :: forall (record :: RopeRec) (mantle :: [Strand]) (core :: BinEff).
Cochoice core =>
Profunctor (Rope record mantle core)
Cochoice
           , Traversing (Rope record mantle core)
Closed (Rope record mantle core)
Traversing (Rope record mantle core)
-> Closed (Rope record mantle core)
-> (forall (f :: * -> *) a b.
    Functor f =>
    Rope record mantle core a b -> Rope record mantle core (f a) (f b))
-> (forall a b s t.
    ((a -> b) -> s -> t)
    -> Rope record mantle core a b -> Rope record mantle core s t)
-> Mapping (Rope record mantle core)
Rope record mantle core a b -> Rope record mantle core (f a) (f b)
((a -> b) -> s -> t)
-> Rope record mantle core a b -> Rope record mantle core s t
forall a b s t.
((a -> b) -> s -> t)
-> Rope record mantle core a b -> Rope record mantle core s t
forall (f :: * -> *) a b.
Functor f =>
Rope record mantle core a b -> Rope record mantle core (f a) (f b)
forall (p :: BinEff).
Traversing p
-> Closed p
-> (forall (f :: * -> *) a b. Functor f => p a b -> p (f a) (f b))
-> (forall a b s t. ((a -> b) -> s -> t) -> p a b -> p s t)
-> Mapping p
forall (record :: RopeRec) (mantle :: [Strand]) (core :: BinEff).
Mapping core =>
Traversing (Rope record mantle core)
forall (record :: RopeRec) (mantle :: [Strand]) (core :: BinEff).
Mapping core =>
Closed (Rope record mantle core)
forall (record :: RopeRec) (mantle :: [Strand]) (core :: BinEff) a
       b s t.
Mapping core =>
((a -> b) -> s -> t)
-> Rope record mantle core a b -> Rope record mantle core s t
forall (record :: RopeRec) (mantle :: [Strand]) (core :: BinEff)
       (f :: * -> *) a b.
(Mapping core, 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
$croam :: forall (record :: RopeRec) (mantle :: [Strand]) (core :: BinEff) a
       b s t.
Mapping core =>
((a -> b) -> s -> t)
-> Rope record mantle core a b -> Rope record mantle core s t
map' :: Rope record mantle core a b -> Rope record mantle core (f a) (f b)
$cmap' :: forall (record :: RopeRec) (mantle :: [Strand]) (core :: BinEff)
       (f :: * -> *) a b.
(Mapping core, Functor f) =>
Rope record mantle core a b -> Rope record mantle core (f a) (f b)
$cp2Mapping :: forall (record :: RopeRec) (mantle :: [Strand]) (core :: BinEff).
Mapping core =>
Closed (Rope record mantle core)
$cp1Mapping :: forall (record :: RopeRec) (mantle :: [Strand]) (core :: BinEff).
Mapping core =>
Traversing (Rope record mantle core)
Mapping, Choice (Rope record mantle core)
Strong (Rope record mantle core)
Choice (Rope record mantle core)
-> Strong (Rope record mantle core)
-> (forall (f :: * -> *) a b.
    Traversable f =>
    Rope record mantle core a b -> Rope record mantle core (f a) (f b))
-> (forall a b s t.
    (forall (f :: * -> *). Applicative f => (a -> f b) -> s -> f t)
    -> Rope record mantle core a b -> Rope record mantle core s t)
-> Traversing (Rope record mantle core)
Rope record mantle core a b -> Rope record mantle core (f a) (f b)
(forall (f :: * -> *). Applicative f => (a -> f b) -> s -> f t)
-> Rope record mantle core a b -> Rope record mantle core s t
forall a b s t.
(forall (f :: * -> *). Applicative f => (a -> f b) -> s -> f t)
-> Rope record mantle core a b -> Rope record mantle core s t
forall (f :: * -> *) a b.
Traversable f =>
Rope record mantle core a b -> Rope record mantle core (f a) (f b)
forall (p :: BinEff).
Choice p
-> Strong p
-> (forall (f :: * -> *) a b.
    Traversable f =>
    p a b -> p (f a) (f b))
-> (forall a b s t.
    (forall (f :: * -> *). Applicative f => (a -> f b) -> s -> f t)
    -> p a b -> p s t)
-> Traversing p
forall (record :: RopeRec) (mantle :: [Strand]) (core :: BinEff).
Traversing core =>
Choice (Rope record mantle core)
forall (record :: RopeRec) (mantle :: [Strand]) (core :: BinEff).
Traversing core =>
Strong (Rope record mantle core)
forall (record :: RopeRec) (mantle :: [Strand]) (core :: BinEff) a
       b s t.
Traversing core =>
(forall (f :: * -> *). Applicative f => (a -> f b) -> s -> f t)
-> Rope record mantle core a b -> Rope record mantle core s t
forall (record :: RopeRec) (mantle :: [Strand]) (core :: BinEff)
       (f :: * -> *) a b.
(Traversing core, Traversable f) =>
Rope record mantle core a b -> Rope record mantle core (f a) (f b)
wander :: (forall (f :: * -> *). Applicative f => (a -> f b) -> s -> f t)
-> Rope record mantle core a b -> Rope record mantle core s t
$cwander :: forall (record :: RopeRec) (mantle :: [Strand]) (core :: BinEff) a
       b s t.
Traversing core =>
(forall (f :: * -> *). Applicative f => (a -> f b) -> s -> f t)
-> Rope record mantle core a b -> Rope record mantle core s t
traverse' :: Rope record mantle core a b -> Rope record mantle core (f a) (f b)
$ctraverse' :: forall (record :: RopeRec) (mantle :: [Strand]) (core :: BinEff)
       (f :: * -> *) a b.
(Traversing core, Traversable f) =>
Rope record mantle core a b -> Rope record mantle core (f a) (f b)
$cp2Traversing :: forall (record :: RopeRec) (mantle :: [Strand]) (core :: BinEff).
Traversing core =>
Strong (Rope record mantle core)
$cp1Traversing :: forall (record :: RopeRec) (mantle :: [Strand]) (core :: BinEff).
Traversing core =>
Choice (Rope record mantle core)
Traversing
           , ThrowEffect ex, TryEffect ex
           , SieveTrans f
           , HasAutoIdent eff
           , (a -> b)
-> (c -> d)
-> Rope record mantle core a c
-> Rope record mantle core b d
(a -> b)
-> Rope record mantle core a c -> Rope record mantle core b c
(b -> c)
-> Rope record mantle core a b -> Rope record mantle core a c
(forall a b c d.
 (a -> b)
 -> (c -> d)
 -> Rope record mantle core a c
 -> Rope record mantle core b d)
-> (forall a b c.
    (a -> b)
    -> Rope record mantle core a c -> Rope record mantle core b c)
-> (forall b c a.
    (b -> c)
    -> Rope record mantle core a b -> Rope record mantle core a c)
-> Bifunctor (Rope record mantle core)
forall a b c.
(a -> b)
-> Rope record mantle core a c -> Rope record mantle core b c
forall b c a.
(b -> c)
-> Rope record mantle core a b -> Rope record mantle core a c
forall a b c d.
(a -> b)
-> (c -> d)
-> Rope record mantle core a c
-> Rope record mantle core b d
forall (p :: BinEff).
(forall a b c d. (a -> b) -> (c -> d) -> p a c -> p b d)
-> (forall a b c. (a -> b) -> p a c -> p b c)
-> (forall b c a. (b -> c) -> p a b -> p a c)
-> Bifunctor p
forall (record :: RopeRec) (mantle :: [Strand]) (core :: BinEff) a
       b c.
Bifunctor core =>
(a -> b)
-> Rope record mantle core a c -> Rope record mantle core b c
forall (record :: RopeRec) (mantle :: [Strand]) (core :: BinEff) b
       c a.
Bifunctor core =>
(b -> c)
-> Rope record mantle core a b -> Rope record mantle core a c
forall (record :: RopeRec) (mantle :: [Strand]) (core :: BinEff) a
       b c d.
Bifunctor core =>
(a -> b)
-> (c -> d)
-> Rope record mantle core a c
-> Rope record mantle core b d
second :: (b -> c)
-> Rope record mantle core a b -> Rope record mantle core a c
$csecond :: forall (record :: RopeRec) (mantle :: [Strand]) (core :: BinEff) b
       c a.
Bifunctor core =>
(b -> c)
-> Rope record mantle core a b -> Rope record mantle core a c
first :: (a -> b)
-> Rope record mantle core a c -> Rope record mantle core b c
$cfirst :: forall (record :: RopeRec) (mantle :: [Strand]) (core :: BinEff) a
       b c.
Bifunctor core =>
(a -> b)
-> Rope record mantle core a c -> Rope record mantle core b c
bimap :: (a -> b)
-> (c -> d)
-> Rope record mantle core a c
-> Rope record mantle core b d
$cbimap :: forall (record :: RopeRec) (mantle :: [Strand]) (core :: BinEff) a
       b c d.
Bifunctor core =>
(a -> b)
-> (c -> d)
-> Rope record mantle core a c
-> Rope record mantle core b d
Bifunctor, Bifunctor (Rope record mantle core)
a -> b -> Rope record mantle core a b
Bifunctor (Rope record mantle core)
-> (forall a b. a -> b -> Rope record mantle core a b)
-> (forall a b c d.
    Rope record mantle core (a -> b) (c -> d)
    -> Rope record mantle core a c -> Rope record mantle core b d)
-> (forall a b c d e f.
    (a -> b -> c)
    -> (d -> e -> f)
    -> Rope record mantle core a d
    -> Rope record mantle core b e
    -> Rope record mantle core c f)
-> (forall a b c d.
    Rope record mantle core a b
    -> Rope record mantle core c d -> Rope record mantle core c d)
-> (forall a b c d.
    Rope record mantle core a b
    -> Rope record mantle core c d -> Rope record mantle core a b)
-> Biapplicative (Rope record mantle core)
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
Rope record mantle core (a -> b) (c -> d)
-> Rope record mantle core a c -> Rope record mantle core b d
(a -> b -> c)
-> (d -> e -> f)
-> Rope record mantle core a d
-> Rope record mantle core b e
-> Rope record mantle core c f
forall a b. a -> b -> Rope record mantle core a b
forall a b c d.
Rope record mantle core a b
-> Rope record mantle core c d -> Rope record mantle core a b
forall a b c d.
Rope record mantle core a b
-> Rope record mantle core c d -> Rope record mantle core c d
forall a b c d.
Rope record mantle core (a -> b) (c -> d)
-> Rope record mantle core a c -> Rope record mantle core b d
forall a b c d e f.
(a -> b -> c)
-> (d -> e -> f)
-> Rope record mantle core a d
-> Rope record mantle core b e
-> Rope record mantle core c f
forall (p :: BinEff).
Bifunctor p
-> (forall a b. a -> b -> p a b)
-> (forall a b c d. p (a -> b) (c -> d) -> p a c -> p b d)
-> (forall a b c d e f.
    (a -> b -> c) -> (d -> e -> f) -> p a d -> p b e -> p c f)
-> (forall a b c d. p a b -> p c d -> p c d)
-> (forall a b c d. p a b -> p c d -> p a b)
-> Biapplicative p
forall (record :: RopeRec) (mantle :: [Strand]) (core :: BinEff).
Biapplicative core =>
Bifunctor (Rope record mantle core)
forall (record :: RopeRec) (mantle :: [Strand]) (core :: BinEff) a
       b.
Biapplicative core =>
a -> b -> Rope record mantle core a b
forall (record :: RopeRec) (mantle :: [Strand]) (core :: BinEff) a
       b c d.
Biapplicative core =>
Rope record mantle core a b
-> Rope record mantle core c d -> Rope record mantle core a b
forall (record :: RopeRec) (mantle :: [Strand]) (core :: BinEff) a
       b c d.
Biapplicative core =>
Rope record mantle core a b
-> Rope record mantle core c d -> Rope record mantle core c d
forall (record :: RopeRec) (mantle :: [Strand]) (core :: BinEff) a
       b c d.
Biapplicative core =>
Rope record mantle core (a -> b) (c -> d)
-> Rope record mantle core a c -> Rope record mantle core b d
forall (record :: RopeRec) (mantle :: [Strand]) (core :: BinEff) a
       b c d e f.
Biapplicative core =>
(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 a b
$c<<* :: forall (record :: RopeRec) (mantle :: [Strand]) (core :: BinEff) a
       b c d.
Biapplicative core =>
Rope record mantle core a b
-> Rope record mantle core c d -> Rope record mantle core a b
*>> :: Rope record mantle core a b
-> Rope record mantle core c d -> Rope record mantle core c d
$c*>> :: forall (record :: RopeRec) (mantle :: [Strand]) (core :: BinEff) a
       b c d.
Biapplicative core =>
Rope record mantle core a b
-> Rope record mantle core c d -> Rope record mantle core c 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
$cbiliftA2 :: forall (record :: RopeRec) (mantle :: [Strand]) (core :: BinEff) a
       b c d e f.
Biapplicative core =>
(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) (c -> d)
-> Rope record mantle core a c -> Rope record mantle core b d
$c<<*>> :: forall (record :: RopeRec) (mantle :: [Strand]) (core :: BinEff) a
       b c d.
Biapplicative core =>
Rope record mantle core (a -> b) (c -> d)
-> Rope record mantle core a c -> Rope record mantle core b d
bipure :: a -> b -> Rope record mantle core a b
$cbipure :: forall (record :: RopeRec) (mantle :: [Strand]) (core :: BinEff) a
       b.
Biapplicative core =>
a -> b -> Rope record mantle core a b
$cp1Biapplicative :: forall (record :: RopeRec) (mantle :: [Strand]) (core :: BinEff).
Biapplicative core =>
Bifunctor (Rope record mantle core)
Biapplicative
           )

runRope :: Rope record mantle core a b -> record (Weaver core) mantle -> core a b
runRope :: Rope record mantle core a b
-> record (Weaver core) mantle -> core a b
runRope (Rope (RopeRunner record (Weaver core) mantle -> core a b
f)) = record (Weaver core) mantle -> core a b
f
{-# INLINE runRope #-}

mkRope :: (record (Weaver core) mantle -> core a b) -> Rope record mantle core a b
mkRope :: (record (Weaver core) mantle -> core a b)
-> Rope record mantle core a b
mkRope = RopeRunner record mantle core core a b
-> Rope record mantle core a b
forall (record :: RopeRec) (mantle :: [Strand]) (core :: BinEff) a
       b.
RopeRunner record mantle core core a b
-> Rope record mantle core a b
Rope (RopeRunner record mantle core core a b
 -> Rope record mantle core a b)
-> ((record (Weaver core) mantle -> core a b)
    -> RopeRunner record mantle core core a b)
-> (record (Weaver core) mantle -> core a b)
-> Rope record mantle core a b
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. (record (Weaver core) mantle -> core a b)
-> RopeRunner record mantle core core a b
forall (record :: RopeRec) (mantle :: [Strand]) (interp :: BinEff)
       (core :: BinEff) a b.
(record (Weaver interp) mantle -> core a b)
-> RopeRunner record mantle interp core a b
RopeRunner
{-# INLINE mkRope #-}

-- | Applies a function on the core action of the Rope
mapRopeCore :: (core a b -> core a' b') -> Rope r m core a b -> Rope r m core a' b'
mapRopeCore :: (core a b -> core a' b')
-> Rope r m core a b -> Rope r m core a' b'
mapRopeCore core a b -> core a' b'
f Rope r m core a b
rope = (r (Weaver core) m -> core a' b') -> Rope r m core a' b'
forall (record :: RopeRec) (core :: BinEff) (mantle :: [Strand]) a
       b.
(record (Weaver core) mantle -> core a b)
-> Rope record mantle core a b
mkRope ((r (Weaver core) m -> core a' b') -> Rope r m core a' b')
-> (r (Weaver core) m -> core a' b') -> Rope r m core a' b'
forall a b. (a -> b) -> a -> b
$ core a b -> core a' b'
f (core a b -> core a' b')
-> (r (Weaver core) m -> core a b)
-> r (Weaver core) m
-> core a' b'
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. Rope r m core a b -> r (Weaver core) m -> core a b
forall (record :: RopeRec) (mantle :: [Strand]) (core :: BinEff) a
       b.
Rope record mantle core a b
-> record (Weaver core) mantle -> core a b
runRope Rope r m core a b
rope
{-# INLINE mapRopeCore #-}

-- | A 'Rope' that is "tight", meaning you cannot 'weave' new 'Strand's to
-- it. The 'strand' function is @O(1)@ on 'TightRope's whatever the number of
-- 'Strand's.
type TightRope = Rope ARec

-- | A 'Rope' that is "loose", meaning you can 'weave' new 'Strand's to
-- it. The 'strand' function is @O(n)@ on 'LooseRope's, @n@ being the number of
-- 'Strand's.
type LooseRope = Rope Rec

-- | Tells that a strand of effects '(l,eff) is present in the rope
type family InRope l eff rope where
  InRope l eff (Rope record mantle core) =
    ( HasField record l mantle mantle eff eff
    , RecElemFCtx record (Weaver core) )

strand :: (InRope l eff (Rope r m c))
       => Label l -> eff :-> Rope r m c
strand :: Label l -> eff :-> Rope r m c
strand Label l
l eff a b
eff = (r (Weaver c) m -> c a b) -> Rope r m c a b
forall (record :: RopeRec) (core :: BinEff) (mantle :: [Strand]) a
       b.
(record (Weaver core) mantle -> core a b)
-> Rope record mantle core a b
mkRope ((r (Weaver c) m -> c a b) -> Rope r m c a b)
-> (r (Weaver c) m -> c a b) -> Rope r m c a b
forall a b. (a -> b) -> a -> b
$ \r (Weaver c) m
r -> Weaver c (l ::: eff) -> StrandEff (l ::: eff) a b -> c a b
forall (interp :: BinEff) (strand :: Strand).
Weaver interp strand
-> forall a b. StrandEff strand a b -> interp a b
weaveStrand (Label l -> r (Weaver c) m -> Weaver c (l ::: eff)
forall k (l :: Symbol) (f :: (Symbol, k) -> *) (v :: k)
       (record :: ((Symbol, k) -> *) -> [(Symbol, k)] -> *)
       (us :: [(Symbol, k)]).
(HasField record l us us v v, RecElemFCtx record f) =>
Label l -> record f us -> f (l ::: v)
rgetf Label l
l r (Weaver c) m
r) eff a b
StrandEff (l ::: eff) a b
eff
{-# INLINE strand #-}

mapStrand :: (InRope l eff (Rope r m c))
          => Label l -> (eff :-> eff) -> Rope r m c :-> Rope r m c
mapStrand :: Label l -> (eff :-> eff) -> Rope r m c :-> Rope r m c
mapStrand Label l
l eff :-> eff
f Rope r m c a b
rope =
  (r (Weaver c) m -> c a b) -> Rope r m c a b
forall (record :: RopeRec) (core :: BinEff) (mantle :: [Strand]) a
       b.
(record (Weaver core) mantle -> core a b)
-> Rope record mantle core a b
mkRope ((r (Weaver c) m -> c a b) -> Rope r m c a b)
-> (r (Weaver c) m -> c a b) -> Rope r m c a b
forall a b. (a -> b) -> a -> b
$ Rope r m c a b -> r (Weaver c) m -> c a b
forall (record :: RopeRec) (mantle :: [Strand]) (core :: BinEff) a
       b.
Rope record mantle core a b
-> record (Weaver core) mantle -> core a b
runRope Rope r m c a b
rope (r (Weaver c) m -> c a b)
-> (r (Weaver c) m -> r (Weaver c) m) -> r (Weaver c) m -> c a b
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. ((Weaver c (l ::: eff) -> Identity (Weaver c (l ::: eff)))
 -> r (Weaver c) m -> Identity (r (Weaver c) m))
-> (Weaver c (l ::: eff) -> Weaver c (l ::: eff))
-> r (Weaver c) m
-> r (Weaver c) m
forall (p :: BinEff) (p :: BinEff) a b a c.
(Profunctor p, Profunctor p) =>
(p a (Identity b) -> p a (Identity c)) -> p a b -> p a c
over (Label l
-> (Weaver c (l ::: eff) -> Identity (Weaver c (l ::: eff)))
-> r (Weaver c) m
-> Identity (r (Weaver c) m)
forall k (l :: Symbol) (v :: k)
       (record :: ((Symbol, k) -> *) -> [(Symbol, k)] -> *) (g :: * -> *)
       (f :: (Symbol, k) -> *) (us :: [(Symbol, k)]).
(Functor g, HasField record l us us v v, RecElemFCtx record f) =>
Label l
-> (f (l ::: v) -> g (f (l ::: v)))
-> record f us
-> g (record f us)
rlensfL Label l
l) (\(Weaver StrandEff (l ::: eff) :-> c
w) -> (StrandEff (l ::: eff) :-> c) -> Weaver c (l ::: eff)
forall (interp :: BinEff) (strand :: Strand).
(forall a b. StrandEff strand a b -> interp a b)
-> Weaver interp strand
Weaver ((StrandEff (l ::: eff) :-> c) -> Weaver c (l ::: eff))
-> (StrandEff (l ::: eff) :-> c) -> Weaver c (l ::: eff)
forall a b. (a -> b) -> a -> b
$ eff a b -> c a b
StrandEff (l ::: eff) :-> c
w (eff a b -> c a b) -> (eff a b -> eff a b) -> eff a b -> c a b
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. eff a b -> eff a b
eff :-> eff
f)
  where
    over :: (p a (Identity b) -> p a (Identity c)) -> p a b -> p a c
over p a (Identity b) -> p a (Identity c)
l p a b
f = Identity c -> c
forall a. Identity a -> a
getIdentity (Identity c -> c) -> p a (Identity c) -> p a c
forall (p :: BinEff) a b c (q :: BinEff).
(Profunctor p, Coercible c b) =>
q b c -> p a b -> p a c
#. p a (Identity b) -> p a (Identity c)
l (b -> Identity b
forall a. a -> Identity a
Identity (b -> Identity b) -> p a b -> p a (Identity b)
forall (p :: BinEff) a b c (q :: BinEff).
(Profunctor p, Coercible c b) =>
q b c -> p a b -> p a c
#. p a b
f) -- we don't depend on lens
{-# INLINE mapStrand #-}

-- | Tells whether a collection of @strands@ is in a 'Rope'.
type family rope `Entwines` (strands::[Strand]) :: Constraint where
  rope `Entwines` '[] = ()
  rope `Entwines` ('(name, eff) ': strands ) = ( InRope name eff rope
                                               , rope `Entwines` strands )

-- | Tells whether a type satisfies all the given constraints.
type family (x::k) `SatisfiesAll` (csts::[k -> Constraint]) :: Constraint where
  x `SatisfiesAll` '[] = ()
  x `SatisfiesAll` (c1 ': cnsts) = ( c1 x, x `SatisfiesAll` cnsts)

-- | 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 AnyRopeWith strands coreConstraints a b = forall mantle r core.
  (Rope r mantle core `Entwines` strands, core `SatisfiesAll` coreConstraints)
  => Rope r mantle core a b

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

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

-- | Useful for functions that want to use tighten/loosen
type AllInMantle strands mantle core =
  ( NatToInt (RLength mantle)
  , RecApplicative mantle
  , RPureConstrained (IndexableField mantle) mantle
  , LooseRope mantle core `Entwines` strands
  , TightRope mantle core `Entwines` strands )
  -- vinyl constraints make it so we have to repeat the Entwines constraint, as
  -- we need it for both tight and loose ropes here

-- | Turn a 'LooseRope' into a 'TightRope'
tighten :: (RecApplicative m, RPureConstrained (IndexableField m) m)
        => LooseRope m core :-> TightRope m core
tighten :: LooseRope m core :-> TightRope m core
tighten LooseRope m core a b
r = (ARec (Weaver core) m -> core a b) -> Rope ARec m core a b
forall (record :: RopeRec) (core :: BinEff) (mantle :: [Strand]) a
       b.
(record (Weaver core) mantle -> core a b)
-> Rope record mantle core a b
mkRope ((ARec (Weaver core) m -> core a b) -> Rope ARec m core a b)
-> (ARec (Weaver core) m -> core a b) -> Rope ARec m core a b
forall a b. (a -> b) -> a -> b
$ LooseRope m core a b -> Rec (Weaver core) m -> core a b
forall (record :: RopeRec) (mantle :: [Strand]) (core :: BinEff) a
       b.
Rope record mantle core a b
-> record (Weaver core) mantle -> core a b
runRope LooseRope m core a b
r (Rec (Weaver core) m -> core a b)
-> (ARec (Weaver core) m -> Rec (Weaver core) m)
-> ARec (Weaver core) m
-> core a b
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. ARec (Weaver core) m -> Rec (Weaver core) m
forall u (f :: u -> *) (ts :: [u]).
(RecApplicative ts, RPureConstrained (IndexableField ts) ts) =>
ARec f ts -> Rec f ts
fromARec
{-# INLINE tighten #-}

-- | Turn a 'TightRope' into a 'LooseRope'. This is very often the first step
-- in a chain of 'weave's.
loosen :: (NatToInt (RLength m))
       => TightRope m core :-> LooseRope m core
loosen :: TightRope m core :-> LooseRope m core
loosen TightRope m core a b
r = (Rec (Weaver core) m -> core a b) -> Rope Rec m core a b
forall (record :: RopeRec) (core :: BinEff) (mantle :: [Strand]) a
       b.
(record (Weaver core) mantle -> core a b)
-> Rope record mantle core a b
mkRope ((Rec (Weaver core) m -> core a b) -> Rope Rec m core a b)
-> (Rec (Weaver core) m -> core a b) -> Rope Rec m core a b
forall a b. (a -> b) -> a -> b
$ TightRope m core a b -> ARec (Weaver core) m -> core a b
forall (record :: RopeRec) (mantle :: [Strand]) (core :: BinEff) a
       b.
Rope record mantle core a b
-> record (Weaver core) mantle -> core a b
runRope TightRope m core a b
r (ARec (Weaver core) m -> core a b)
-> (Rec (Weaver core) m -> ARec (Weaver core) m)
-> Rec (Weaver core) m
-> core a b
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. Rec (Weaver core) m -> ARec (Weaver core) m
forall k (f :: k -> *) (ts :: [k]).
NatToInt (RLength ts) =>
Rec f ts -> ARec f ts
toARec
{-# INLINE loosen #-}

-- | 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
  :: 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.
weave :: Label name
-> ((LooseRope ('(name, binEff) : mantle) core :-> core)
    -> binEff :-> core)
-> LooseRope ('(name, binEff) : mantle) core
   :-> LooseRope mantle core
weave Label name
_ (LooseRope ('(name, binEff) : mantle) core :-> core)
-> binEff :-> core
interpFn LooseRope ('(name, binEff) : mantle) core a b
rope = (Rec (Weaver core) mantle -> core a b) -> Rope Rec mantle core a b
forall (record :: RopeRec) (core :: BinEff) (mantle :: [Strand]) a
       b.
(record (Weaver core) mantle -> core a b)
-> Rope record mantle core a b
mkRope ((Rec (Weaver core) mantle -> core a b)
 -> Rope Rec mantle core a b)
-> (Rec (Weaver core) mantle -> core a b)
-> Rope Rec mantle core a b
forall a b. (a -> b) -> a -> b
$ \Rec (Weaver core) mantle
r ->
  let runThatRope :: LooseRope ('(name,binEff) ': mantle) core :-> core
      runThatRope :: LooseRope ('(name, binEff) : mantle) core a b -> core a b
runThatRope LooseRope ('(name, binEff) : mantle) core a b
rope' =
        LooseRope ('(name, binEff) : mantle) core a b
-> Rec (Weaver core) ('(name, binEff) : mantle) -> core a b
forall (record :: RopeRec) (mantle :: [Strand]) (core :: BinEff) a
       b.
Rope record mantle core a b
-> record (Weaver core) mantle -> core a b
runRope LooseRope ('(name, binEff) : mantle) core a b
rope' ((StrandEff '(name, binEff) :-> core) -> Weaver core '(name, binEff)
forall (interp :: BinEff) (strand :: Strand).
(forall a b. StrandEff strand a b -> interp a b)
-> Weaver interp strand
Weaver ((LooseRope ('(name, binEff) : mantle) core :-> core)
-> binEff :-> core
interpFn LooseRope ('(name, binEff) : mantle) core :-> core
runThatRope) Weaver core '(name, binEff)
-> Rec (Weaver core) mantle
-> Rec (Weaver core) ('(name, binEff) : mantle)
forall u (a :: u -> *) (r :: u) (rs :: [u]).
a r -> Rec a rs -> Rec a (r : rs)
:& Rec (Weaver core) mantle
r)
  in LooseRope ('(name, binEff) : mantle) core a b -> core a b
LooseRope ('(name, binEff) : mantle) core :-> core
runThatRope LooseRope ('(name, binEff) : mantle) core a b
rope

-- | 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
-- @
--
weave'
  :: 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.
weave' :: Label name
-> (binEff :-> core)
-> LooseRope ('(name, binEff) : mantle) core
   :-> LooseRope mantle core
weave' Label name
lbl binEff :-> core
interpFn = Label name
-> ((LooseRope ('(name, binEff) : mantle) core :-> core)
    -> binEff :-> core)
-> LooseRope ('(name, binEff) : mantle) core
   :-> LooseRope mantle core
forall (name :: Symbol) (binEff :: BinEff) (mantle :: [Strand])
       (core :: BinEff).
Label name
-> ((LooseRope ('(name, binEff) : mantle) core :-> core)
    -> binEff :-> core)
-> LooseRope ('(name, binEff) : mantle) core
   :-> LooseRope mantle core
weave Label name
lbl ((binEff a b -> core a b)
-> (LooseRope ('(name, binEff) : mantle) core Any Any
    -> core Any Any)
-> binEff a b
-> core a b
forall a b. a -> b -> a
const binEff a b -> core a b
binEff :-> core
interpFn)
{-# INLINE weave' #-}

-- | A shortcut for 'weave'' when your core 'HasKleisli'
weaveK :: (HasKleisli m core)
       => Label name
       -> (forall a b. binEff a b -> a -> m b)
       -> (LooseRope ('(name,binEff) ': mantle) core :-> LooseRope mantle core)
weaveK :: Label name
-> (forall a b. binEff a b -> a -> m b)
-> LooseRope ('(name, binEff) : mantle) core
   :-> LooseRope mantle core
weaveK Label name
lbl forall a b. binEff a b -> a -> m b
interpFn = Label name
-> (binEff :-> core)
-> LooseRope ('(name, binEff) : mantle) core
   :-> LooseRope mantle core
forall (name :: Symbol) (binEff :: BinEff) (mantle :: [Strand])
       (core :: BinEff).
Label name
-> (binEff :-> core)
-> LooseRope ('(name, binEff) : mantle) core
   :-> LooseRope mantle core
weave' Label name
lbl ((a -> m b) -> core a b
forall (m :: * -> *) (eff :: BinEff) a b.
HasKleisli m eff =>
(a -> m b) -> eff a b
liftKleisli ((a -> m b) -> core a b)
-> (binEff a b -> a -> m b) -> binEff a b -> core a b
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. binEff a b -> a -> m b
forall a b. binEff a b -> a -> m b
interpFn)
{-# INLINE weaveK #-}

-- | Supports 'weaveAll' over any 'Rope'
class WeaveAll mantle core where
  -- | 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'.
  weaveAll :: (forall lbl eff. lbl -> eff :-> core)
           -> LooseRope mantle core
          :-> core

instance WeaveAll '[] core where
  weaveAll :: (forall lbl (eff :: BinEff). lbl -> eff :-> core)
-> LooseRope '[] core :-> core
weaveAll forall lbl (eff :: BinEff). lbl -> eff :-> core
_ = LooseRope '[] core a b -> core a b
forall (core :: BinEff). LooseRope '[] core :-> core
untwine
  {-# INLINE weaveAll #-}

instance {-# OVERLAPPABLE #-} (WeaveAll mantle core)
  => WeaveAll ((name:::eff) ': mantle) core where
  weaveAll :: (forall lbl (eff :: BinEff). lbl -> eff :-> core)
-> LooseRope ((name ::: eff) : mantle) core :-> core
weaveAll forall lbl (eff :: BinEff). lbl -> eff :-> core
interpFn = (forall lbl (eff :: BinEff). lbl -> eff :-> core)
-> LooseRope mantle core :-> core
forall (mantle :: [Strand]) (core :: BinEff).
WeaveAll mantle core =>
(forall lbl (eff :: BinEff). lbl -> eff :-> core)
-> LooseRope mantle core :-> core
weaveAll forall lbl (eff :: BinEff). lbl -> eff :-> core
interpFn
                    (LooseRope mantle core a b -> core a b)
-> (LooseRope ((name ::: eff) : mantle) core a b
    -> LooseRope mantle core a b)
-> LooseRope ((name ::: eff) : mantle) core a b
-> core a b
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. Label name
-> (eff :-> core)
-> LooseRope ((name ::: eff) : mantle) core
   :-> LooseRope mantle core
forall (name :: Symbol) (binEff :: BinEff) (mantle :: [Strand])
       (core :: BinEff).
Label name
-> (binEff :-> core)
-> LooseRope ('(name, binEff) : mantle) core
   :-> LooseRope mantle core
weave' Label name
lbl (Label name -> eff :-> core
forall lbl (eff :: BinEff). lbl -> eff :-> core
interpFn Label name
lbl)
    where lbl :: Label name
lbl = forall a. IsLabel name a => a
forall (x :: Symbol) a. IsLabel x a => a
fromLabel @name

-- | Reorders the strands to match some external context. @strands'@ can contain
-- more elements than @strands@. Note it works on both 'TightRope's and
-- 'LooseRope's
retwine :: (RetwinableAs r strands core strands')
        => Rope r strands core
       :-> Rope r strands' core
retwine :: Rope r strands core :-> Rope r strands' core
retwine Rope r strands core a b
r = (r (Weaver core) strands' -> core a b) -> Rope r strands' core a b
forall (record :: RopeRec) (core :: BinEff) (mantle :: [Strand]) a
       b.
(record (Weaver core) mantle -> core a b)
-> Rope record mantle core a b
mkRope ((r (Weaver core) strands' -> core a b)
 -> Rope r strands' core a b)
-> (r (Weaver core) strands' -> core a b)
-> Rope r strands' core a b
forall a b. (a -> b) -> a -> b
$ Rope r strands core a b -> r (Weaver core) strands -> core a b
forall (record :: RopeRec) (mantle :: [Strand]) (core :: BinEff) a
       b.
Rope record mantle core a b
-> record (Weaver core) mantle -> core a b
runRope Rope r strands core a b
r (r (Weaver core) strands -> core a b)
-> (r (Weaver core) strands' -> r (Weaver core) strands)
-> r (Weaver core) strands'
-> core a b
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. r (Weaver core) strands' -> r (Weaver core) strands
forall k1 k2 (rs :: [k1]) (ss :: [k1]) (f :: k2 -> *)
       (record :: (k2 -> *) -> [k1] -> *) (is :: [Nat]).
(RecSubset record rs ss is, RecSubsetFCtx record f) =>
record f ss -> record f rs
rcast
{-# INLINE retwine #-}

-- | Merge two strands that have the same effect type. Keeps the first name.
mergeStrands :: Label n1
             -> Label n2
             -> LooseRope ( '(n1,binEff) ': '(n2,binEff) ': mantle ) core
            :-> LooseRope ( '(n1,binEff) ': mantle ) core
mergeStrands :: Label n1
-> Label n2
-> LooseRope ('(n1, binEff) : '(n2, binEff) : mantle) core
   :-> LooseRope ('(n1, binEff) : mantle) core
mergeStrands Label n1
_ Label n2
_ LooseRope ('(n1, binEff) : '(n2, binEff) : mantle) core a b
rope = (Rec (Weaver core) ('(n1, binEff) : mantle) -> core a b)
-> Rope Rec ('(n1, binEff) : mantle) core a b
forall (record :: RopeRec) (core :: BinEff) (mantle :: [Strand]) a
       b.
(record (Weaver core) mantle -> core a b)
-> Rope record mantle core a b
mkRope ((Rec (Weaver core) ('(n1, binEff) : mantle) -> core a b)
 -> Rope Rec ('(n1, binEff) : mantle) core a b)
-> (Rec (Weaver core) ('(n1, binEff) : mantle) -> core a b)
-> Rope Rec ('(n1, binEff) : mantle) core a b
forall a b. (a -> b) -> a -> b
$ \(r :: Weaver core r
r@(Weaver StrandEff r :-> core
w) :& Rec (Weaver core) rs
rest) ->
  LooseRope ('(n1, binEff) : '(n2, binEff) : mantle) core a b
-> Rec (Weaver core) ('(n1, binEff) : '(n2, binEff) : mantle)
-> core a b
forall (record :: RopeRec) (mantle :: [Strand]) (core :: BinEff) a
       b.
Rope record mantle core a b
-> record (Weaver core) mantle -> core a b
runRope LooseRope ('(n1, binEff) : '(n2, binEff) : mantle) core a b
rope (Weaver core r
r Weaver core r
-> Rec (Weaver core) ('(n2, binEff) : rs)
-> Rec (Weaver core) (r : '(n2, binEff) : rs)
forall u (a :: u -> *) (r :: u) (rs :: [u]).
a r -> Rec a rs -> Rec a (r : rs)
:& (StrandEff '(n2, binEff) :-> core) -> Weaver core '(n2, binEff)
forall (interp :: BinEff) (strand :: Strand).
(forall a b. StrandEff strand a b -> interp a b)
-> Weaver interp strand
Weaver StrandEff r :-> core
StrandEff '(n2, binEff) :-> core
w Weaver core '(n2, binEff)
-> Rec (Weaver core) rs -> Rec (Weaver core) ('(n2, binEff) : rs)
forall u (a :: u -> *) (r :: u) (rs :: [u]).
a r -> Rec a rs -> Rec a (r : rs)
:& Rec (Weaver core) rs
rest)
{-# INLINE mergeStrands #-}

-- | Strips a 'Rope' of its empty mantle. Usually the last step of the
-- interpretation of a 'Rope'.
untwine :: LooseRope '[] core :-> core
untwine :: LooseRope '[] core a b -> core a b
untwine LooseRope '[] core a b
r = LooseRope '[] core a b -> Rec (Weaver core) '[] -> core a b
forall (record :: RopeRec) (mantle :: [Strand]) (core :: BinEff) a
       b.
Rope record mantle core a b
-> record (Weaver core) mantle -> core a b
runRope LooseRope '[] core a b
r Rec (Weaver core) '[]
forall u (a :: u -> *). Rec a '[]
RNil
{-# INLINE untwine #-}