-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Generic programming with systems of recursive datatypes -- -- Many generic programs require information about the recursive -- positions of a datatype. Examples include the generic fold, generic -- rewriting or the Zipper data structure. Several generic programming -- systems allow to write such functions by viewing datatypes as fixed -- points of a pattern functor. Traditionally, this view has been limited -- to so-called regular datatypes such as lists and binary trees. In -- particular, systems of mutually recursive datatypes have been -- excluded. -- -- With the multirec library, we provide a mechanism to talk about fixed -- points of systems of datatypes that may be mutually recursive. On top -- of this representations, generic functions such as the fold or the -- Zipper can then be defined. -- -- We expect that the library will be especially interesting for compiler -- writers, because ASTs are typically systems of mutually recursive -- datatypes, and with multirec it becomes easy to write generic -- functions on ASTs. -- -- The library is based on ideas described in the paper: -- -- @package multirec @version 0.2 -- | This module contains a class for datatypes that represent data -- constructors. module Generics.MultiRec.Constructor -- | Class for datatypes that represent data constructors. For non-symbolic -- constructors, only conName has to be defined. The weird -- argument is supposed to be instantiated with C from base, hence the -- complex kind. class Constructor c conName :: (Constructor c) => t c (f :: (* -> *) -> (* -> *) -> * -> *) (s :: * -> *) (r :: * -> *) ix -> String conFixity :: (Constructor c) => t c (f :: (* -> *) -> (* -> *) -> * -> *) (s :: * -> *) (r :: * -> *) ix -> Fixity -- | Datatype to represent the fixity of a constructor. An infix -- declaration directly corresponds to an application of Infix. data Fixity Prefix :: Fixity Infix :: Associativity -> Int -> Fixity data Associativity LeftAssociative :: Associativity RightAssociative :: Associativity NotAssociative :: Associativity instance Eq Associativity instance Show Associativity instance Ord Associativity instance Read Associativity instance Eq Fixity instance Show Fixity instance Ord Fixity instance Read Fixity -- | This module is the base of the multirec library. It defines the view -- of a system of datatypes: All the datatypes of the system are -- represented as indexed functors that are built up from the structure -- types defined in this module. Furthermore, in order to use the library -- for a system, conversion functions have to be defined between the -- original datatypes and their representation. The type class that holds -- these conversion functions are also defined here. module Generics.MultiRec.Base -- | Represents recursive positions. The first argument indicates which -- type (within the system) to recurse on. data I :: * -> (* -> *) -> (* -> *) -> * -> * I :: r xi -> I xi s r ix -- | Destructor for I. unI :: I xi s r ix -> r xi -- | Represents constant types that do not belong to the system. data K a s :: (* -> *) r :: (* -> *) ix K :: a -> K a ix unK :: K a ix -> a -- | Represents constructors without fields. data U s :: (* -> *) r :: (* -> *) ix U :: U ix -- | Represents sums (choices between constructors). data (:+:) f g s :: (* -> *) r :: (* -> *) ix L :: (f s r ix) -> :+: f g ix R :: (g s r ix) -> :+: f g ix -- | Represents products (sequences of fields of a constructor). data (:*:) f g s :: (* -> *) r :: (* -> *) ix (:*:) :: f s r ix -> g s r ix -> :*: f g ix -- | Is used to indicate the type (within the system) that a particular -- constructor injects to. data (:>:) :: ((* -> *) -> (* -> *) -> * -> *) -> * -> (* -> *) -> (* -> *) -> * -> * Tag :: f s r ix -> (f :>: ix) s r ix -- | Destructor for '(:>:)'. unTag :: (f :>: ix) s r ix -> f s r ix -- | Represents constructors. data C c f s :: (* -> *) r :: (* -> *) ix C :: f s r ix -> C c f s r ix -- | Destructor for C. unC :: C c f s r ix -> f s r ix -- | Unlifted version of I. newtype I0 a I0 :: a -> I0 a unI0 :: I0 a -> a -- | Unlifted version of K. newtype K0 a b K0 :: a -> K0 a b unK0 :: K0 a b -> a -- | Type family describing the pattern functor of a system. type Str s ix = (PF s) s I0 ix class Ix s ix from_ :: (Ix s ix) => ix -> Str s ix to_ :: (Ix s ix) => Str s ix -> ix from :: (Ix s ix, pfs ~ (PF s)) => ix -> pfs s I0 ix to :: (Ix s ix, pfs ~ (PF s)) => pfs s I0 ix -> ix index :: (Ix s ix) => s ix instance Functor (K0 a) instance Applicative I0 instance Functor I0 -- | This module contains Template Haskell code that can be used to -- automatically generate the boilerplate code for the multiplate -- library. The constructor information can be generated per datatype, -- the rest per system of datatypes. module Generics.MultiRec.TH -- | Given a list of datatype names, derive datatypes and instances of -- class Constructor. deriveConstructors :: [Name] -> Q [Dec] -- | Given the name of the index GADT, the names of the types in the -- system, and the name (as string) for the pattern functor to derive, -- generate the Ix and PF instances. IMPORTANT: It -- is assumed that the constructors of the GADT have the same names as -- the datatypes in the family. deriveSystem :: Name -> [Name] -> String -> Q [Dec] -- | Derive only the PF instance. Not needed if deriveSystem -- is used. derivePF :: String -> [Name] -> Q [Dec] -- | Derive only the Ix instances. Not needed if deriveSystem -- is used. deriveIx :: Name -> [Name] -> Q [Dec] instance Lift Associativity instance Lift Fixity -- | Generic function that returns the constructor names available in a -- system of datatypes. module Generics.MultiRec.ConNames class ConNames f :: ((* -> *) -> (* -> *) -> * -> *) hconNames :: (ConNames f) => f s r ix -> [String] conNames :: (Ix s ix, ConNames (PF s)) => s ix -> [String] instance (ConNames f) => ConNames (f :>: ix) instance ConNames (I a) instance ConNames (f :*: g) instance ConNames U instance ConNames (K x) instance (ConNames f, ConNames g) => ConNames (f :+: g) instance (Constructor c) => ConNames (C c f) -- | The definition of functorial map. module Generics.MultiRec.HFunctor class HFunctor f hmapA :: (HFunctor f, Applicative a) => (forall ix. (Ix s ix) => s ix -> r ix -> a (r' ix)) -> f s r ix -> a (f s r' ix) -- | The function hmap takes a functor f. All the recursive -- instances in that functor are wrapped by an application of r. -- The argument to hmap takes a function that transformes -- r occurrences into r' occurrences, for every -- ix. In order to associate the index ix with the -- correct system s, the argument to hmap is -- additionally parameterized by a witness of type s ix. hmap :: (HFunctor f) => (forall ix. (Ix s ix) => s ix -> r ix -> r' ix) -> f s r ix -> f s r' ix -- | Monadic version of hmap. hmapM :: (HFunctor f, Monad m) => (forall ix. (Ix s ix) => s ix -> r ix -> m (r' ix)) -> f s r ix -> m (f s r' ix) instance (HFunctor f) => HFunctor (C c f) instance (HFunctor f) => HFunctor (f :>: ix) instance (HFunctor f, HFunctor g) => HFunctor (f :*: g) instance (HFunctor f, HFunctor g) => HFunctor (f :+: g) instance HFunctor U instance HFunctor (K x) instance HFunctor (I xi) -- | Higher-order fixed point operator as well as conversion functions. It -- is rarely necessary to use HFix. Generic functions usually -- convert between the original datatype and the functor directly. module Generics.MultiRec.HFix data HFix h :: ((* -> *) -> * -> *) ix HIn :: h (HFix h) ix -> HFix ix hout :: HFix ix -> h (HFix h) ix hfrom :: (pfs ~ (PF s), Ix s ix, HFunctor (PF s)) => ix -> HFix (pfs s) ix hto :: (pfs ~ (PF s), Ix s ix, HFunctor (PF s)) => HFix (pfs s) ix -> ix -- | The definition of generic fold, unfold, paramorphisms. In addition, -- some combinators that facilitate the construction of algebras. -- -- There are several variants of fold in other modules that are probably -- easier to use: -- -- module Generics.MultiRec.Fold type Algebra' s f r = forall ix. (Ix s ix) => s ix -> f s r ix -> r ix type Algebra s r = Algebra' s (PF s) r type AlgebraF' s f g r = forall ix. (Ix s ix) => s ix -> f s r ix -> g (r ix) type AlgebraF s g r = AlgebraF' s (PF s) g r fold :: (Ix s ix, HFunctor (PF s)) => Algebra s r -> ix -> r ix foldM :: (Ix s ix, HFunctor (PF s), Monad m) => AlgebraF s m r -> ix -> m (r ix) type CoAlgebra' s f r = forall ix. (Ix s ix) => s ix -> r ix -> f s r ix type CoAlgebra s r = CoAlgebra' s (PF s) r type CoAlgebraF' s f g r = forall ix. (Ix s ix) => s ix -> r ix -> g (f s r ix) type CoAlgebraF s g r = CoAlgebraF' s (PF s) g r unfold :: (Ix s ix, HFunctor (PF s)) => CoAlgebra s r -> r ix -> ix unfoldM :: (Ix s ix, HFunctor (PF s), Monad m) => CoAlgebraF s m r -> r ix -> m ix type ParaAlgebra' s f r = forall ix. (Ix s ix) => s ix -> f s r ix -> ix -> r ix type ParaAlgebra s r = ParaAlgebra' s (PF s) r type ParaAlgebraF' s f g r = forall ix. (Ix s ix) => s ix -> f s r ix -> ix -> g (r ix) type ParaAlgebraF s g r = ParaAlgebraF' s (PF s) g r para :: (Ix s ix, HFunctor (PF s)) => ParaAlgebra s r -> ix -> r ix paraM :: (Ix s ix, HFunctor (PF s), Monad m) => ParaAlgebraF s m r -> ix -> m (r ix) type AlgPart a s :: (* -> *) r ix = a s r ix -> r ix type :-> f g s :: (* -> *) r :: (* -> *) ix = f s r ix -> g s r ix (&) :: (AlgPart a :-> (AlgPart b :-> AlgPart (a :+: b))) s r ix tag :: AlgPart a s r ix -> AlgPart (a :>: ix) s r ix' con :: AlgPart a s r ix -> AlgPart (C c a) s r ix -- | Variant of Generics.MultiRec.Fold where the result type is -- independent of the index. module Generics.MultiRec.FoldK type Algebra' s f r = forall ix. (Ix s ix) => s ix -> f s (K0 r) ix -> r type Algebra s r = Algebra' s (PF s) r type AlgebraF' s f g r = forall ix. (Ix s ix) => s ix -> f s (K0 r) ix -> g r type AlgebraF s g r = AlgebraF' s (PF s) g r fold :: (Ix s ix, HFunctor (PF s)) => Algebra s r -> ix -> r foldM :: (Ix s ix, HFunctor (PF s), Monad m) => AlgebraF s m r -> ix -> m r type CoAlgebra' s f r = forall ix. (Ix s ix) => s ix -> r -> f s (K0 r) ix type CoAlgebra s r = CoAlgebra' s (PF s) r type CoAlgebraF' s f g r = forall ix. (Ix s ix) => s ix -> r -> g (f s (K0 r) ix) type CoAlgebraF s g r = CoAlgebraF' s (PF s) g r unfold :: (Ix s ix, HFunctor (PF s)) => CoAlgebra s r -> r -> ix unfoldM :: (Ix s ix, HFunctor (PF s), Monad m) => CoAlgebraF s m r -> r -> m ix type ParaAlgebra' s f r = forall ix. (Ix s ix) => s ix -> f s (K0 r) ix -> ix -> r type ParaAlgebra s r = ParaAlgebra' s (PF s) r type ParaAlgebraF' s f g r = forall ix. (Ix s ix) => s ix -> f s (K0 r) ix -> ix -> g r type ParaAlgebraF s g r = ParaAlgebraF' s (PF s) g r para :: (Ix s ix, HFunctor (PF s)) => ParaAlgebra s r -> ix -> r paraM :: (Ix s ix, HFunctor (PF s), Monad m) => ParaAlgebraF s m r -> ix -> m r type AlgPart a s :: (* -> *) b ix = a s (K0 b) ix -> b type :-> f g s :: (* -> *) b ix = f s b ix -> g s b ix (&) :: (AlgPart a :-> (AlgPart b :-> AlgPart (a :+: b))) s c ix tag :: AlgPart a s c ix -> AlgPart (a :>: ix) s c ix' con :: AlgPart a s b ix -> AlgPart (C c a) s b ix -- | A variant of fold that allows the specification of the algebra in a -- convenient way. module Generics.MultiRec.FoldAlg -- | The type family we use to describe the convenient algebras. -- | The algebras passed to the fold have to work for all index types in -- the system. The additional witness argument is required only to make -- GHC's typechecker happy. type Algebra s r = forall ix. (Ix s ix) => s ix -> Alg (PF s) s r ix -- | The class fold explains how to convert a convenient algebra Alg -- back into a function from functor to result, as required by the -- standard fold function. class Fold f :: ((* -> *) -> (* -> *) -> * -> *) alg :: (Fold f, Ix s ix) => Alg f s r ix -> f s r ix -> r ix -- | Variant of fold that takes an additional witness argument. fold_ :: (Ix s ix, HFunctor (PF s), Fold (PF s)) => s ix -> Algebra s r -> ix -> r ix -- | Fold with convenient algebras. fold :: (Ix s ix, HFunctor (PF s), Fold (PF s)) => Algebra s r -> ix -> r ix -- | For constructing algebras that are made of nested pairs rather than -- n-ary tuples, it is helpful to use this pairing combinator. (&) :: a -> b -> (a, b) instance (Fold f) => Fold (C c f) instance (Fold f) => Fold (f :>: xi) instance (Fold g) => Fold (I xi :*: g) instance (Fold g) => Fold (K a :*: g) instance (Fold f, Fold g) => Fold (f :+: g) instance Fold (I xi) instance Fold U instance Fold (K a) -- | A variant of fold that allows the specification of the algebra in a -- convenient way, and that fixes the result type to a constant. module Generics.MultiRec.FoldAlgK -- | The type family we use to describe the convenient algebras. -- | The algebras passed to the fold have to work for all index types in -- the system. The additional witness argument is required only to make -- GHC's typechecker happy. type Algebra s r = forall ix. (Ix s ix) => s ix -> Alg (PF s) s r -- | The class fold explains how to convert a convenient algebra Alg -- back into a function from functor to result, as required by the -- standard fold function. class Fold f :: ((* -> *) -> (* -> *) -> * -> *) alg :: (Fold f, Ix s ix) => Alg f s r -> f s (K0 r) ix -> r -- | Variant of fold that takes an additional witness argument. fold_ :: (Ix s ix, HFunctor (PF s), Fold (PF s)) => s ix -> Algebra s r -> ix -> r -- | Fold with convenient algebras. fold :: (Ix s ix, HFunctor (PF s), Fold (PF s)) => Algebra s r -> ix -> r -- | For constructing algebras that are made of nested pairs rather than -- n-ary tuples, it is helpful to use this pairing combinator. (&) :: a -> b -> (a, b) instance (Fold f) => Fold (C c f) instance (Fold f) => Fold (f :>: xi) instance (Fold g) => Fold (I xi :*: g) instance (Fold g) => Fold (K a :*: g) instance (Fold f, Fold g) => Fold (f :+: g) instance Fold (I xi) instance Fold U instance Fold (K a) -- | The compos operator, inspired by -- -- B. Bringert and A. Ranta A pattern for almost compositional functions -- ICFP 2006 module Generics.MultiRec.Compos -- | Normal version. compos :: (Ix s ix, HFunctor (PF s)) => (forall ix. (Ix s ix) => s ix -> ix -> ix) -> ix -> ix -- | Monadic version of compos. composM :: (Ix s ix, HFunctor (PF s), Monad m) => (forall ix. (Ix s ix) => s ix -> ix -> m ix) -> ix -> m ix -- | Applicative version of compos. composA :: (Ix s ix, HFunctor (PF s), Applicative a) => (forall ix. (Ix s ix) => s ix -> ix -> a ix) -> ix -> a ix -- | Generic equality. module Generics.MultiRec.Eq class HEq f heq :: (HEq f) => s ix -> (forall ix. (Ix s ix) => s ix -> r ix -> r ix -> Bool) -> f s r ix -> f s r ix -> Bool eq :: (Ix s ix, HEq (PF s)) => s ix -> ix -> ix -> Bool instance (HEq f) => HEq (C c f) instance (HEq f) => HEq (f :>: ix) instance (HEq f, HEq g) => HEq (f :*: g) instance (HEq f, HEq g) => HEq (f :+: g) instance HEq U instance (Eq x) => HEq (K x) instance HEq (I xi) -- | Generic show. module Generics.MultiRec.Show class (HFunctor f) => HShow f hShowsPrecAlg :: (HShow f) => Algebra' s f (K0 [Int -> ShowS]) -- | A variant of the algebra that takes an extra argument to fix the -- system s the algebra works on. hShowsPrecAlg_ :: (HShow f) => s ix -> Algebra' s f (K0 [Int -> ShowS]) showsPrec :: (Ix s ix, HShow (PF s)) => s ix -> Int -> ix -> ShowS show :: (Ix s ix, HShow (PF s)) => s ix -> ix -> String spaces :: [ShowS] -> ShowS instance (HShow f) => HShow (C c f) instance (HShow f) => HShow (f :>: ix) instance (HShow f, HShow g) => HShow (f :*: g) instance (HShow f, HShow g) => HShow (f :+: g) instance HShow U instance (Show x) => HShow (K x) instance HShow (I xi) -- | multirec -- generic programming with systems of recursive datatypes -- -- This top-level module re-exports all other modules of the library. module Generics.MultiRec