Safe Haskell | None |
---|---|
Language | Haskell2010 |
Synopsis
- data Atom kon
- data NA :: (kon -> *) -> (Nat -> *) -> Atom kon -> * where
- mapNA :: (forall k. ki k -> kj k) -> (forall ix. IsNat ix => f ix -> g ix) -> NA ki f a -> NA kj g a
- mapNAM :: Monad m => (forall k. ki k -> m (kj k)) -> (forall ix. IsNat ix => f ix -> m (g ix)) -> NA ki f a -> m (NA kj g a)
- elimNA :: (forall k. ki k -> b) -> (forall k. IsNat k => phi k -> b) -> NA ki phi a -> b
- zipNA :: NA ki f a -> NA kj g a -> NA (ki :*: kj) (f :*: g) a
- eqNA :: (forall k. ki k -> ki k -> Bool) -> (forall ix. fam ix -> fam ix -> Bool) -> NA ki fam l -> NA ki fam l -> Bool
- newtype Rep (ki :: kon -> *) (phi :: Nat -> *) (code :: [[Atom kon]]) = Rep {}
- type PoA (ki :: kon -> *) (phi :: Nat -> *) = NP (NA ki phi)
- mapRep :: (forall ix. IsNat ix => f ix -> g ix) -> Rep ki f c -> Rep ki g c
- mapRepM :: Monad m => (forall ix. IsNat ix => f ix -> m (g ix)) -> Rep ki f c -> m (Rep ki g c)
- bimapRep :: (forall k. ki k -> kj k) -> (forall ix. IsNat ix => f ix -> g ix) -> Rep ki f c -> Rep kj g c
- bimapRepM :: Monad m => (forall k. ki k -> m (kj k)) -> (forall ix. IsNat ix => f ix -> m (g ix)) -> Rep ki f c -> m (Rep kj g c)
- zipRep :: MonadPlus m => Rep ki f c -> Rep kj g c -> m (Rep (ki :*: kj) (f :*: g) c)
- elimRepM :: Monad m => (forall k. ki k -> m a) -> (forall k. IsNat k => f k -> m a) -> ([a] -> m b) -> Rep ki f c -> m b
- elimRep :: (forall k. ki k -> a) -> (forall k. IsNat k => f k -> a) -> ([a] -> b) -> Rep ki f c -> b
- eqRep :: (forall k. ki k -> ki k -> Bool) -> (forall ix. fam ix -> fam ix -> Bool) -> Rep ki fam c -> Rep ki fam c -> Bool
- data Constr :: [k] -> Nat -> * where
- injNS :: Constr sum n -> PoA ki fam (Lkup n sum) -> NS (NP (NA ki fam)) sum
- inj :: Constr sum n -> PoA ki fam (Lkup n sum) -> Rep ki fam sum
- matchNS :: Constr sum c -> NS (NP (NA ki fam)) sum -> Maybe (PoA ki fam (Lkup c sum))
- match :: Constr sum c -> Rep ki fam sum -> Maybe (PoA ki fam (Lkup c sum))
- data View :: (kon -> *) -> (Nat -> *) -> [[Atom kon]] -> * where
- sop :: Rep ki fam sum -> View ki fam sum
- fromView :: View ki fam sum -> Rep ki fam sum
- newtype Fix (ki :: kon -> *) (codes :: [[[Atom kon]]]) (n :: Nat) = Fix {}
- cata :: IsNat ix => (forall iy. IsNat iy => Rep ki phi (Lkup iy codes) -> phi iy) -> Fix ki codes ix -> phi ix
- cataM :: (Monad m, IsNat ix) => (forall iy. IsNat iy => Rep ki phi (Lkup iy codes) -> m (phi iy)) -> Fix ki codes ix -> m (phi ix)
- proxyFixIdx :: phi ix -> Proxy ix
- snatFixIdx :: IsNat ix => phi ix -> SNat ix
- mapFixM :: Monad m => (forall k. ki k -> m (kj k)) -> Fix ki fam ix -> m (Fix kj fam ix)
- eqFix :: (forall k. ki k -> ki k -> Bool) -> Fix ki fam ix -> Fix ki fam ix -> Bool
- heqFixIx :: (IsNat ix, IsNat ix') => Fix ki fam ix -> Fix ki fam ix' -> Maybe (ix :~: ix')
Universe of Codes
We will use nested lists to represent the Sums-of-Products structure. The atoms, however, will be parametrized by a kind used to index what are the types that are opaque to the library.
Atoms can be either opaque types, kon
, or
type variables, Nat
.
Instances
Family Singl FamRose CodesRose Source # | |
HasDatatypeInfo Singl FamRose CodesRose Source # | |
Defined in Generics.MRSOP.Examples.RoseTree datatypeInfo :: Proxy FamRose -> SNat ix -> DatatypeInfo (Lkup ix CodesRose) Source # | |
Eq kon => Eq (Atom kon) Source # | |
Show kon => Show (Atom kon) Source # | |
TestEquality ki => TestEquality (NA ki phi :: Atom kon -> Type) Source # | |
Defined in Generics.MRSOP.Base.Universe | |
(ShowHO ki, ShowHO phi) => ShowHO (Rep ki phi :: [[Atom kon]] -> Type) Source # | |
(ShowHO phi, ShowHO ki) => ShowHO (NA ki phi :: Atom kon -> Type) Source # | |
(EqHO phi, EqHO ki) => EqHO (Rep ki phi :: [[Atom kon]] -> Type) Source # | |
(EqHO phi, EqHO ki) => EqHO (NA ki phi :: Atom kon -> Type) Source # | |
(EqHO phi, EqHO ki) => EqHO (Holes ki codes phi :: Atom kon -> Type) Source # | |
(HasDatatypeInfo ki fam codes, ShowHO ki, ShowHO f, ShowHO ann) => ShowHO (HolesAnn ann ki codes f :: Atom kon -> Type) Source # | |
(HasDatatypeInfo ki fam codes, ShowHO ki, ShowHO f) => Show (Holes ki codes f at) Source # | |
data NA :: (kon -> *) -> (Nat -> *) -> Atom kon -> * where Source #
NA ki phi a
provides an interpretation for an atom a
,
using either ki
or phi
to interpret the type variable
or opaque type.
Map, Elim and Zip
mapNA :: (forall k. ki k -> kj k) -> (forall ix. IsNat ix => f ix -> g ix) -> NA ki f a -> NA kj g a Source #
Maps a natural transformation over an atom interpretation
mapNAM :: Monad m => (forall k. ki k -> m (kj k)) -> (forall ix. IsNat ix => f ix -> m (g ix)) -> NA ki f a -> m (NA kj g a) Source #
Maps a monadic natural transformation over an atom interpretation
elimNA :: (forall k. ki k -> b) -> (forall k. IsNat k => phi k -> b) -> NA ki phi a -> b Source #
Eliminates an atom interpretation
eqNA :: (forall k. ki k -> ki k -> Bool) -> (forall ix. fam ix -> fam ix -> Bool) -> NA ki fam l -> NA ki fam l -> Bool Source #
Compares atoms provided we know how to compare the leaves, both recursive and constant.
Representation of Codes
Codes are represented using the Rep
newtype,
which wraps an n-ary sum of n-ary products. Note it receives two
functors: ki
and phi
, to interpret opaque types and type variables
respectively.
newtype Rep (ki :: kon -> *) (phi :: Nat -> *) (code :: [[Atom kon]]) Source #
Representation of codes.
type PoA (ki :: kon -> *) (phi :: Nat -> *) = NP (NA ki phi) Source #
Product of Atoms is a handy synonym to have.
Map, Elim and Zip
Just like for NS
, NP
and NA
, we provide
a couple convenient functions working over
a Rep
. These are just the cannonical combination
of their homonym versions in NS
, NP
or NA
.
mapRep :: (forall ix. IsNat ix => f ix -> g ix) -> Rep ki f c -> Rep ki g c Source #
Maps over a representation.
mapRepM :: Monad m => (forall ix. IsNat ix => f ix -> m (g ix)) -> Rep ki f c -> m (Rep ki g c) Source #
Maps a monadic function over a representation.
bimapRep :: (forall k. ki k -> kj k) -> (forall ix. IsNat ix => f ix -> g ix) -> Rep ki f c -> Rep kj g c Source #
Maps over both indexes of a representation.
bimapRepM :: Monad m => (forall k. ki k -> m (kj k)) -> (forall ix. IsNat ix => f ix -> m (g ix)) -> Rep ki f c -> m (Rep kj g c) Source #
Monadic version of bimapRep
zipRep :: MonadPlus m => Rep ki f c -> Rep kj g c -> m (Rep (ki :*: kj) (f :*: g) c) Source #
Zip two representations together, in case they are made with the same constructor.
zipRep (Here (NA_I x :* NP0)) (Here (NA_I y :* NP0)) = return $ Here (NA_I (x :*: y) :* NP0)
zipRep (Here (NA_I x :* NP0)) (There (Here ...)) = mzero
elimRepM :: Monad m => (forall k. ki k -> m a) -> (forall k. IsNat k => f k -> m a) -> ([a] -> m b) -> Rep ki f c -> m b Source #
elimRep :: (forall k. ki k -> a) -> (forall k. IsNat k => f k -> a) -> ([a] -> b) -> Rep ki f c -> b Source #
Pure eliminator.
eqRep :: (forall k. ki k -> ki k -> Bool) -> (forall ix. fam ix -> fam ix -> Bool) -> Rep ki fam c -> Rep ki fam c -> Bool Source #
SOP functionality
It is often more convenient to view a value of Rep
as a constructor and its fields, instead of having to
traverse the inner NS
structure.
data Constr :: [k] -> Nat -> * where Source #
A value c :: Constr ks n
specifies a position
in a type-level list. It is, in fact, isomorphic to Fin (length ks)
.
injNS :: Constr sum n -> PoA ki fam (Lkup n sum) -> NS (NP (NA ki fam)) sum Source #
We can define injections into an n-ary sum from
its Constr
uctors
inj :: Constr sum n -> PoA ki fam (Lkup n sum) -> Rep ki fam sum Source #
Wrap it in a Rep
for convenience.
matchNS :: Constr sum c -> NS (NP (NA ki fam)) sum -> Maybe (PoA ki fam (Lkup c sum)) Source #
Inverse of injNS
. Given some Constructor, see if Rep is of this constructor
match :: Constr sum c -> Rep ki fam sum -> Maybe (PoA ki fam (Lkup c sum)) Source #
Inverse of inj
. Given some Constructor, see if Rep is of this constructor
data View :: (kon -> *) -> (Nat -> *) -> [[Atom kon]] -> * where Source #
Finally, we can view a sum-of-products as a constructor and a product-of-atoms.
Least Fixpoints
Finally we tie the recursive knot. Given an interpretation
for the constant types, a family of sums-of-products and
an index ix
into such family, we take the least fixpoint of
the representation of the code indexed by ix
newtype Fix (ki :: kon -> *) (codes :: [[[Atom kon]]]) (n :: Nat) Source #
Indexed least fixpoints
:: IsNat ix | |
=> (forall iy. IsNat iy => Rep ki phi (Lkup iy codes) -> phi iy) | |
-> Fix ki codes ix | |
-> phi ix |
Catamorphism over fixpoints
:: (Monad m, IsNat ix) | |
=> (forall iy. IsNat iy => Rep ki phi (Lkup iy codes) -> m (phi iy)) | |
-> Fix ki codes ix | |
-> m (phi ix) |
Monadic variant
proxyFixIdx :: phi ix -> Proxy ix Source #
Retrieves the index of a Fix
mapFixM :: Monad m => (forall k. ki k -> m (kj k)) -> Fix ki fam ix -> m (Fix kj fam ix) Source #
Maps over the values of opaque types within the fixpoint.