| Safe Haskell | None |
|---|---|
| Language | Haskell2010 |
Data.Finitary.PolyRep
Description
A normalized polynomial representation for finitary polynomial functors.
Compared with Data.Finitary.TreeRep, this module forgets the syntactic tree structure of sums and products and represents a functor as
x^n1 + x^n2 + ... + x^nk
This is especially useful for Day convolution: monomials satisfy
Day x^m x^n ≅ x^(m*n)
which is implemented by DayPoly, fromDay, and toDay.
The list order in Poly is operationally significant in Haskell, but
mathematically it should be regarded as a chosen ordering of summands.
Synopsis
- type Poly = [Nat]
- zeroPoly :: Poly
- addPoly :: Poly -> Poly -> Poly
- onePoly :: Poly
- multPoly :: Poly -> Poly -> Poly
- parPoly :: Poly
- type AddPoly (r1 :: Poly) (r2 :: Poly) = r1 ++ r2
- type family MultPoly (r1 :: Poly) (r2 :: Poly) :: Poly where ...
- type family DayPoly (r1 :: Poly) (r2 :: Poly) :: Poly where ...
- data SPoly (r :: Poly) where
- sAddPoly :: forall (r1 :: Poly) (r2 :: Poly). SPoly r1 -> SPoly r2 -> SPoly (AddPoly r1 r2)
- (%++) :: forall (r1 :: Poly) (r2 :: Poly). SPoly r1 -> SPoly r2 -> SPoly (AddPoly r1 r2)
- sMultPoly :: forall (r1 :: Poly) (r2 :: Poly). SPoly r1 -> SPoly r2 -> SPoly (MultPoly r1 r2)
- sDayPoly :: forall (r1 :: Poly) (r2 :: Poly). SPoly r1 -> SPoly r2 -> SPoly (DayPoly r1 r2)
- class KnownPoly (p :: Poly) where
- withKnownPoly :: forall (r :: Poly) result. SPoly r -> (KnownPoly r => result) -> result
- data Eval (r :: Poly) x where
- absurdEval :: Eval ('[] :: [Nat]) a -> b
- unitEval :: Eval '[0] a
- fromSum :: forall (r1 :: Poly) proxy (r2 :: Poly) x. SPoly r1 -> proxy r2 -> Either (Eval r1 x) (Eval r2 x) -> Eval (r1 ++ r2) x
- inlEval :: forall (r1 :: Poly) proxy (r2 :: [Nat]) x. SPoly r1 -> proxy r2 -> Eval r1 x -> Eval (r1 ++ r2) x
- inrEval :: forall (r1 :: Poly) proxy (r2 :: Poly) x. SPoly r1 -> proxy r2 -> Eval r2 x -> Eval (r1 ++ r2) x
- toSum :: forall (r1 :: Poly) proxy (r2 :: [Nat]) x. SPoly r1 -> proxy r2 -> Eval (r1 ++ r2) x -> Either (Eval r1 x) (Eval r2 x)
- fromProduct :: forall (r1 :: Poly) (r2 :: Poly) x. SPoly r1 -> SPoly r2 -> Eval r1 x -> Eval r2 x -> Eval (MultPoly r1 r2) x
- toProduct :: forall (r1 :: Poly) (r2 :: Poly) x. SPoly r1 -> SPoly r2 -> Eval (MultPoly r1 r2) x -> (Eval r1 x, Eval r2 x)
- fromDay :: forall (r1 :: Poly) (r2 :: Poly) x. SPoly r1 -> SPoly r2 -> Day (Eval r1) (Eval r2) x -> Eval (DayPoly r1 r2) x
- toDay :: forall (r1 :: Poly) (r2 :: Poly) x. SPoly r1 -> SPoly r2 -> Eval (DayPoly r1 r2) x -> Day (Eval r1) (Eval r2) x
- ptraverseEval :: forall p (r :: Poly) a b. (Cartesian p, Cocartesian p) => SPoly r -> p a b -> p (Eval r a) (Eval r b)
- data Encoder a b s t where
- idEncoder :: Encoder a b a b
- (++) :: [a] -> [a] -> [a]
- type family MultPoly1 (e :: Nat) (r2 :: Poly) :: Poly where ...
- type family DayPoly1 (e :: Nat) (r2 :: Poly) :: Poly where ...
Base Type and its algebra
Finitary polynomial f(x) = x^e1 + x^e2 + ... + x^en
represented as a list of exponents [e1, e2, ..., en]
Type-level Poly algebra
data SPoly (r :: Poly) where Source #
Constructors
| SNil :: SPoly ('[] :: [Nat]) | |
| SCons :: forall (e :: Nat) (es :: [Nat]). !(SNat e) -> !(SPoly es) -> SPoly (e ': es) |
sAddPoly :: forall (r1 :: Poly) (r2 :: Poly). SPoly r1 -> SPoly r2 -> SPoly (AddPoly r1 r2) Source #
sMultPoly :: forall (r1 :: Poly) (r2 :: Poly). SPoly r1 -> SPoly r2 -> SPoly (MultPoly r1 r2) Source #
sDayPoly :: forall (r1 :: Poly) (r2 :: Poly). SPoly r1 -> SPoly r2 -> SPoly (DayPoly r1 r2) Source #
Evaluating Poly as a Haskell Functor
data Eval (r :: Poly) x where Source #
Constructors
| EHere :: forall (e :: Nat) x (es :: [Nat]). !(Finite e -> x) -> Eval (e ': es) x | |
| EThere :: forall (es :: [Nat]) x (e :: Nat). !(Eval es x) -> Eval (e ': es) x |
Instances
| KnownPoly r => Eq1 (Eval r) Source # | |
| KnownPoly r => Ord1 (Eval r) Source # | |
Defined in Data.Finitary.PolyRep | |
| KnownPoly r => PTraversable (Eval r) Source # | |
Defined in Data.Finitary.PolyRep 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 # | |
| KnownPoly r => Foldable (Eval r) Source # | |
Defined in Data.Finitary.PolyRep 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 # | |
| KnownPoly r => Traversable (Eval r) Source # | |
| (KnownPoly r, Eq a) => Eq (Eval r a) Source # | |
| (KnownPoly r, Ord a) => Ord (Eval r a) Source # | |
Defined in Data.Finitary.PolyRep | |
Correspondence between sums, products, and Day convolution of Poly and its evaluation
absurdEval :: Eval ('[] :: [Nat]) a -> b Source #
fromSum :: forall (r1 :: Poly) proxy (r2 :: Poly) x. SPoly r1 -> proxy r2 -> Either (Eval r1 x) (Eval r2 x) -> Eval (r1 ++ r2) x Source #
inlEval :: forall (r1 :: Poly) proxy (r2 :: [Nat]) x. SPoly r1 -> proxy r2 -> Eval r1 x -> Eval (r1 ++ r2) x Source #
inrEval :: forall (r1 :: Poly) proxy (r2 :: Poly) x. SPoly r1 -> proxy r2 -> Eval r2 x -> Eval (r1 ++ r2) x Source #
toSum :: forall (r1 :: Poly) proxy (r2 :: [Nat]) x. SPoly r1 -> proxy r2 -> Eval (r1 ++ r2) x -> Either (Eval r1 x) (Eval r2 x) Source #
fromProduct :: forall (r1 :: Poly) (r2 :: Poly) x. SPoly r1 -> SPoly r2 -> Eval r1 x -> Eval r2 x -> Eval (MultPoly r1 r2) x Source #
toProduct :: forall (r1 :: Poly) (r2 :: Poly) x. SPoly r1 -> SPoly r2 -> Eval (MultPoly r1 r2) x -> (Eval r1 x, Eval r2 x) Source #
fromDay :: forall (r1 :: Poly) (r2 :: Poly) x. SPoly r1 -> SPoly r2 -> Day (Eval r1) (Eval r2) x -> Eval (DayPoly r1 r2) x Source #
toDay :: forall (r1 :: Poly) (r2 :: Poly) x. SPoly r1 -> SPoly r2 -> Eval (DayPoly r1 r2) x -> Day (Eval r1) (Eval r2) x Source #
Profunctor traversal
ptraverseEval :: forall p (r :: Poly) a b. (Cartesian p, Cocartesian p) => SPoly r -> p a b -> p (Eval r a) (Eval r b) Source #
Building bidirectional encodings as a Eval r with Profunctor
data Encoder a b s t where Source #
Constructors
| Encoder :: forall (r :: Poly) s a b t. !(SPoly r) -> (s -> Eval r a) -> (Eval r b -> t) -> Encoder a b s t |
Instances
| Cartesian (Encoder a b) Source # | |
Defined in Data.Finitary.PolyRep 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.PolyRep 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.PolyRep 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 # | |
idEncoder :: Encoder a b a b Source #
Encoder for the identity functor.
It can be used to construct an encoder for arbitrary PTraversable
functor using
ptraverseidEncoder:: PTraversable t => Encoder a b (t a) (t b)
.
Internal-only type families
(++) :: [a] -> [a] -> [a] infixr 5 #
(++) appends two lists, i.e.,
[x1, ..., xm] ++ [y1, ..., yn] == [x1, ..., xm, y1, ..., yn] [x1, ..., xm] ++ [y1, ...] == [x1, ..., xm, y1, ...]
If the first list is not finite, the result is the first list.
Performance considerations
This function takes linear time in the number of elements of the
first list. Thus it is better to associate repeated
applications of (++) to the right (which is the default behaviour):
xs ++ (ys ++ zs) or simply xs ++ ys ++ zs, but not (xs ++ ys) ++ zs.
For the same reason concat = foldr (++) []
has linear performance, while foldl (++) [] is prone
to quadratic slowdown
Examples
>>>[1, 2, 3] ++ [4, 5, 6][1,2,3,4,5,6]
>>>[] ++ [1, 2, 3][1,2,3]
>>>[3, 2, 1] ++ [][3,2,1]