| Safe Haskell | None |
|---|---|
| Language | Haskell2010 |
Data.Finitary.TreeRep
Synopsis
- type Rep = [TreeRep]
- data TreeRep
- addRep :: Rep -> Rep -> Rep
- multRep :: Rep -> Rep -> Rep
- emptyRep :: Rep
- unitRep :: Rep
- idRep :: Rep
- maybeRep :: Rep
- type family AddRep (r1 :: Rep) (r2 :: Rep) :: Rep where ...
- type family MultRep (r1 :: Rep) (r2 :: Rep) :: Rep where ...
- data SRep (r :: Rep) where
- data STreeRep (t :: TreeRep) where
- (%++) :: forall (r1 :: Rep) (r2 :: Rep). SRep r1 -> SRep r2 -> SRep (AddRep r1 r2)
- (%*) :: forall (r1 :: Rep) (r2 :: Rep). SRep r1 -> SRep r2 -> SRep (MultRep r1 r2)
- sEmptyRep :: SRep ('[] :: [TreeRep])
- sUnitRep :: SRep '['UnitRep]
- sIdRep :: SRep '['ParRep '['UnitRep]]
- class KnownRep (r :: Rep) where
- class KnownTreeRep (t :: TreeRep) where
- withKnownRep :: forall (r :: Rep) result. SRep r -> (KnownRep r => result) -> result
- withKnownTreeRep :: forall (t :: TreeRep) result. STreeRep t -> (KnownTreeRep t => result) -> result
- data Eval (r :: Rep) a where
- data EvalT (t :: TreeRep) a where
- fromSum :: forall (r1 :: Rep) proxy (r2 :: Rep) x. SRep r1 -> proxy r2 -> Either (Eval r1 x) (Eval r2 x) -> Eval (AddRep r1 r2) x
- inlEval :: forall (r1 :: Rep) proxy (r2 :: Rep) x. SRep r1 -> proxy r2 -> Eval r1 x -> Eval (AddRep r1 r2) x
- inrEval :: forall (r1 :: Rep) proxy (r2 :: Rep) x. SRep r1 -> proxy r2 -> Eval r2 x -> Eval (AddRep r1 r2) x
- toSum :: forall (r1 :: Rep) proxy (r2 :: Rep) x. SRep r1 -> proxy r2 -> Eval (AddRep r1 r2) x -> Either (Eval r1 x) (Eval r2 x)
- fromProduct :: forall (r1 :: Rep) (r2 :: Rep) x. SRep r1 -> SRep r2 -> Eval r1 x -> Eval r2 x -> Eval (MultRep r1 r2) x
- toProduct :: forall (r1 :: Rep) (r2 :: Rep) x. SRep r1 -> SRep r2 -> Eval (MultRep r1 r2) x -> (Eval r1 x, Eval r2 x)
- absurdEval :: Eval ('[] :: [TreeRep]) a -> any
- unitEval :: Eval '['UnitRep] a
- ptraverseEval :: forall p (r :: Rep) a b. (Cartesian p, Cocartesian p) => SRep r -> p a b -> p (Eval r a) (Eval r b)
- ptraverseEvalT :: forall p (t :: TreeRep) a b. (Cartesian p, Cocartesian p) => STreeRep t -> p a b -> p (EvalT t a) (EvalT t b)
- data Encoder a b s t where
- idEncoder :: Encoder a b a b
Base Type and its algebra
Representation of a finitary functor.
If we write {r} to mean the type r :: Rep
represents,
r = [t1, t2, ...]
represent sum type
{t1} + {t2} + ...Theories
Rep can be thought of as a datatype representing
a thing called skew semiring freely generated from one generator.
Semiring is an abstract algebraic structure with addition and multiplication,
but not necessarily have subtraction. Typical instance of semiring is
Integer or Natural.
Skew semiring is another abstract algebraic structure similar to semiring:
it has addition + and multiplication * with their respective units 0 and 1.
What differentiates skew semiring is it distinguishes the order of additions.
In any semiring, x + y and y + x must be equal; but in a skew semiring they can be
different.
Formally, a skew semiring is a set A equipped with two binary operations (+),(*) :: A -> A -> A
and two nullary operations 0,1 :: A, satisfying following equational axioms:
- Addition
(A, (+), 0)is a monoid x + (y + z) === (x + y) + z
x + 0 === x === 0 + x
- Multiplication
(A, (*), 1)is a monoid x * (y * z) === (x * y) * z
x * 1 === x === 1 * x
- Multiplication from right distributes to left addition
0 * z === 0
(x + y) * z === (x * z) + (y * z)
Note that both addition (+) and multiplication (*) are not guaranteed to be commutative,
and distributive law exists only for one side.
Rep can be thought of as the free skew semiring on one generator a,
or in other words the type of normal forms of skew semiring expressions built from
(+,*,0,1) and one variable a.
Rep := 0 | TreeRep + Rep TreeRep := 1 | a * Rep
Why skew semiring, and not a full semiring?
The Enum class assigns every finitary type x a canonical bijection x ≅ Finite n,
giving each value a unique index from 0 to n-1. Two types with the same cardinality
are "equal" in the semiring when this bijection is order-preserving. Under this notion
of equality, the familiar type constructors satisfy some semiring laws but not all:
- Addition is
Either Either a bencodes allLeft-values beforeRight-values. Concatenating the two sequences is order-preserving.- Multiplication is
(,) (a, b)encodes in row-major (lexicographic) order:(a₀,b₀),(a₀,b₁),…,(a₁,b₀),…- Right distributivity holds
(Either a b, c) ≅ Either (a,c) (b,c)is order-preserving: the first|a|·|c|indices map toLeft, the remaining|b|·|c|toRight. ✓- Left distributivity fails
(a, Either b c) ≅ Either (a,b) (a,c)is NOT order-preserving in general. The left side interleavesb- andc-values as it sweeps througha, whereas the right side puts all(a,b)pairs before all(a,c)pairs. ✗- Addition is not commutative
Either a b ≇ Either b aas ordered types: the first putsa-values first, the second putsb-values first.
This is exactly the definition of a skew semiring.
Because Rep is the free skew semiring on one generator, Eval r a describes
finitary functors that respect this structure: given any Enum instance for a,
Eval r a inherits a canonical Enum instance determined entirely by r.
Representation of a simple (= not a sum of multiple reps) finitary functor.
UnitReprepresents a unit type:{UnitRep}(a) = ().ParRep rrepresents a type with one parameter type prepended:{ParRep r}(a) = (a, {r}(a)).
Example representations
Type-level Rep algebra
data SRep (r :: Rep) where Source #
Singleton value for type-level Rep
Constructors
| SEmpty :: SRep ('[] :: [TreeRep]) | |
| SCase :: forall (t :: TreeRep) (r1 :: [TreeRep]). !(STreeRep t) -> !(SRep r1) -> SRep (t ': r1) |
data STreeRep (t :: TreeRep) where Source #
Singleton value for type-level TreeRep
Instances
| Show (STreeRep t) Source # | |
| Eq (STreeRep r) Source # | |
| Ord (STreeRep r) Source # | |
Defined in Data.Finitary.TreeRep | |
(%++) :: forall (r1 :: Rep) (r2 :: Rep). SRep r1 -> SRep r2 -> SRep (AddRep r1 r2) Source #
Compute the witness of AddRep
(%*) :: forall (r1 :: Rep) (r2 :: Rep). SRep r1 -> SRep r2 -> SRep (MultRep r1 r2) Source #
Compute the witness of MultRep
class KnownTreeRep (t :: TreeRep) where Source #
withKnownTreeRep :: forall (t :: TreeRep) result. STreeRep t -> (KnownTreeRep t => result) -> result Source #
Evaluating Rep as a Haskell Functor
data Eval (r :: Rep) a where Source #
Constructors
| EHere :: forall (t :: TreeRep) a (r1 :: [TreeRep]). !(EvalT t a) -> Eval (t ': r1) a | |
| EThere :: forall (r1 :: [TreeRep]) a (t :: TreeRep). !(Eval r1 a) -> Eval (t ': r1) a |
Instances
| Eq1 (Eval r) Source # | |
| Ord1 (Eval r) Source # | |
Defined in Data.Finitary.TreeRep | |
| KnownRep r => PTraversable (Eval r) Source # | |
Defined in Data.Finitary.TreeRep Methods ptraverseWith :: (Cartesian p, Cocartesian p) => (as -> Eval r a) -> (Eval r b -> bs) -> p a b -> p as bs Source # | |
| Functor (Eval r) Source # | |
| Foldable (Eval r) Source # | |
Defined in Data.Finitary.TreeRep Methods fold :: Monoid m => Eval r m -> m # foldMap :: Monoid m => (a -> m) -> Eval r a -> m # foldMap' :: Monoid m => (a -> m) -> Eval r a -> m # foldr :: (a -> b -> b) -> b -> Eval r a -> b # foldr' :: (a -> b -> b) -> b -> Eval r a -> b # foldl :: (b -> a -> b) -> b -> Eval r a -> b # foldl' :: (b -> a -> b) -> b -> Eval r a -> b # foldr1 :: (a -> a -> a) -> Eval r a -> a # foldl1 :: (a -> a -> a) -> Eval r a -> a # elem :: Eq a => a -> Eval r a -> Bool # maximum :: Ord a => Eval r a -> a # minimum :: Ord a => Eval r a -> a # | |
| Traversable (Eval r) Source # | |
| Eq a => Eq (Eval r a) Source # | |
| Ord a => Ord (Eval r a) Source # | |
Defined in Data.Finitary.TreeRep | |
data EvalT (t :: TreeRep) a where Source #
Constructors
| EUnit :: forall a. EvalT 'UnitRep a | |
| EPar :: forall a (r :: Rep). a -> Eval r a -> EvalT ('ParRep r) a |
Instances
| Eq1 (EvalT t) Source # | |
| Ord1 (EvalT t) Source # | |
Defined in Data.Finitary.TreeRep | |
| KnownTreeRep t => PTraversable (EvalT t) Source # | |
Defined in Data.Finitary.TreeRep Methods ptraverseWith :: (Cartesian p, Cocartesian p) => (as -> EvalT t a) -> (EvalT t b -> bs) -> p a b -> p as bs Source # | |
| Functor (EvalT t) Source # | |
| Foldable (EvalT t) Source # | |
Defined in Data.Finitary.TreeRep Methods fold :: Monoid m => EvalT t m -> m # foldMap :: Monoid m => (a -> m) -> EvalT t a -> m # foldMap' :: Monoid m => (a -> m) -> EvalT t a -> m # foldr :: (a -> b -> b) -> b -> EvalT t a -> b # foldr' :: (a -> b -> b) -> b -> EvalT t a -> b # foldl :: (b -> a -> b) -> b -> EvalT t a -> b # foldl' :: (b -> a -> b) -> b -> EvalT t a -> b # foldr1 :: (a -> a -> a) -> EvalT t a -> a # foldl1 :: (a -> a -> a) -> EvalT t a -> a # elem :: Eq a => a -> EvalT t a -> Bool # maximum :: Ord a => EvalT t a -> a # minimum :: Ord a => EvalT t a -> a # | |
| Traversable (EvalT t) Source # | |
| Eq a => Eq (EvalT t a) Source # | |
| Ord a => Ord (EvalT t a) Source # | |
Correspondence between sums and products of Rep and its evaluation
fromSum :: forall (r1 :: Rep) proxy (r2 :: Rep) x. SRep r1 -> proxy r2 -> Either (Eval r1 x) (Eval r2 x) -> Eval (AddRep r1 r2) x Source #
inlEval :: forall (r1 :: Rep) proxy (r2 :: Rep) x. SRep r1 -> proxy r2 -> Eval r1 x -> Eval (AddRep r1 r2) x Source #
inrEval :: forall (r1 :: Rep) proxy (r2 :: Rep) x. SRep r1 -> proxy r2 -> Eval r2 x -> Eval (AddRep r1 r2) x Source #
toSum :: forall (r1 :: Rep) proxy (r2 :: Rep) x. SRep r1 -> proxy r2 -> Eval (AddRep r1 r2) x -> Either (Eval r1 x) (Eval r2 x) Source #
fromProduct :: forall (r1 :: Rep) (r2 :: Rep) x. SRep r1 -> SRep r2 -> Eval r1 x -> Eval r2 x -> Eval (MultRep r1 r2) x Source #
toProduct :: forall (r1 :: Rep) (r2 :: Rep) x. SRep r1 -> SRep r2 -> Eval (MultRep r1 r2) x -> (Eval r1 x, Eval r2 x) Source #
absurdEval :: Eval ('[] :: [TreeRep]) a -> any Source #
Profunctor traversal
ptraverseEval :: forall p (r :: Rep) a b. (Cartesian p, Cocartesian p) => SRep r -> p a b -> p (Eval r a) (Eval r b) Source #
ptraverseEvalT :: forall p (t :: TreeRep) a b. (Cartesian p, Cocartesian p) => STreeRep t -> p a b -> p (EvalT t a) (EvalT t b) Source #
Building bidirectional encodings as a Eval r with Profunctor
data Encoder a b s t where Source #
Constructors
| Encoder :: forall (r :: Rep) s a b t. !(SRep r) -> (s -> Eval r a) -> (Eval r b -> t) -> Encoder a b s t |
Instances
| Cartesian (Encoder a b) Source # | |
Defined in Data.Finitary.TreeRep Methods proUnit :: Encoder a b a0 () Source # proProduct :: (a0 -> (a1, a2)) -> ((b1, b2) -> b0) -> Encoder a b a1 b1 -> Encoder a b a2 b2 -> Encoder a b a0 b0 Source # (***) :: Encoder a b a0 b0 -> Encoder a b a' b' -> Encoder a b (a0, a') (b0, b') Source # (&&&) :: Encoder a b a0 b0 -> Encoder a b a0 b' -> Encoder a b a0 (b0, b') Source # proPower :: forall (n :: Nat) a0 b0. KnownNat n => Encoder a b a0 b0 -> Encoder a b (Finite n -> a0) (Finite n -> b0) Source # | |
| Cocartesian (Encoder a b) Source # | |
Defined in Data.Finitary.TreeRep Methods proEmpty :: Encoder a b Void b0 Source # proSum :: (a0 -> Either a1 a2) -> (Either b1 b2 -> b0) -> Encoder a b a1 b1 -> Encoder a b a2 b2 -> Encoder a b a0 b0 Source # (+++) :: Encoder a b a0 b0 -> Encoder a b a' b' -> Encoder a b (Either a0 a') (Either b0 b') Source # (|||) :: Encoder a b a0 b0 -> Encoder a b a' b0 -> Encoder a b (Either a0 a') b0 Source # proTimes :: forall (n :: Nat) a0 b0. KnownNat n => Encoder a b a0 b0 -> Encoder a b (Finite n, a0) (Finite n, b0) Source # | |
| Profunctor (Encoder a b) Source # | |
Defined in Data.Finitary.TreeRep Methods dimap :: (a0 -> b0) -> (c -> d) -> Encoder a b b0 c -> Encoder a b a0 d # lmap :: (a0 -> b0) -> Encoder a b b0 c -> Encoder a b a0 c # rmap :: (b0 -> c) -> Encoder a b a0 b0 -> Encoder a b a0 c # (#.) :: forall a0 b0 c q. Coercible c b0 => q b0 c -> Encoder a b a0 b0 -> Encoder a b a0 c # (.#) :: forall a0 b0 c q. Coercible b0 a0 => Encoder a b b0 c -> q a0 b0 -> Encoder a b a0 c # | |
| Functor (Encoder a b s) Source # | |