circuits-0.1.0.0: src/Circuit.hs
-- | Circuit: free traced monoidal categories and hyperfunctions.
--
-- == Usage
--
-- @
-- import Circuit
-- @
--
-- === Lazy feedback (knot-tying)
--
-- Use the @(,@) tensor to tie a lazy knot. The feedback value and output
-- are produced simultaneously.
--
-- >>> let powers (ns, ()) = (1 : map (*2) ns, take 5 ns)
-- >>> trace powers () :: [Integer]
-- [1,2,4,8,16]
--
-- === Iteration
--
-- Use the 'Either' tensor for loops that terminate.
--
-- >>> let step n = if n < 5 then Left (n + 1) else Right n
-- >>> trace (either step step) (0 :: Int)
-- 5
--
-- === Switching between representations
--
-- 'Circuit' is the inspectable GADT form. 'Hyper' is the efficient final
-- encoding. Convert with 'encode' and 'reify'.
--
-- >>> lower (encode (Lift (+1) :: Circuit (->) (,) Int Int)) 41
-- 42
--
-- >>> reify (Knot (\(acc, x) -> (x, acc)) :: Circuit (->) (,) Int Int) 0
-- 0
--
-- == Overview
--
-- This library provides two representations of feedback:
--
-- * 'Circuit' (in "Circuit.Circuit") — the initial, inspectable GADT encoding.
-- * 'Hyper' (in "Circuit.Hyper") — the final, coinductive encoding.
--
-- The 'Trace' class (in "Circuit.Traced") abstracts the choice of tensor,
-- currently supporting lazy knots with @(,@) and iteration with 'Either'.
--
-- All braided, cartesian, and cocartesian structure, plus the general
-- 'ambientBy' state-threading combinator, lives in "Circuit.Monoidal".
--
-- == Core Concepts
--
-- * __Tensor__ (@t@): The bifunctor pairing a feedback value with a payload
-- inside a 'Knot' (currently @(,@) or 'Either').
--
-- * __Feedback value__: The component that travels around the loop (first
-- parameter of the tensor in a 'Knot').
--
-- * __Payload__: The value being transformed and emitted (second parameter
-- of the tensor).
--
-- * __Feedback channel__: The path the feedback value takes when routed back
-- into the next step.
module Circuit
( -- * Circuit
Circuit (..),
Wire,
Step,
reify,
-- * Traced
Trace (..),
cellIO,
-- * Hyper
Hyper (..),
lift,
lower,
base,
push,
run,
encode,
encodeEither,
runEither,
flatten,
-- * Monoidal
Braided (..),
ambient,
assoc,
assoc',
seed,
absorb,
release,
coassoc,
coassoc',
coseed,
coabsorbL,
coabsorbR,
coreleaseL,
coreleaseR,
ambientBy,
)
where
import Circuit.Circuit
( Circuit (..),
Step,
Wire,
reify,
)
import Circuit.Hyper
( Hyper (..),
base,
encode,
encodeEither,
flatten,
lift,
lower,
push,
run,
runEither,
)
import Circuit.Monoidal
( Braided (..),
absorb,
ambient,
ambientBy,
assoc,
assoc',
coabsorbL,
coabsorbR,
coassoc,
coassoc',
coreleaseL,
coreleaseR,
coseed,
release,
seed,
)
import Circuit.Traced
( Trace (..),
cellIO,
)