-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Pointless Haskell library -- -- Pointless Haskell is library for point-free programming with recursion -- patterns defined as hylomorphisms, inspired in ideas from the PolyP -- library. Generic recursion patterns can be expressed for recursive -- types and no support for mutually recursive types or nested data types -- is provided. The library also features the visualization of the -- intermediate data structure of hylomorphisms with GHood -- (http://hackage.haskell.org/cgi-bin/hackage-scripts/package/GHood). @package pointless-haskell @version 0.0.8 -- | Pointless Haskell: point-free programming with recursion patterns as -- hylomorphisms -- -- This module defines many standard combinators used for point-free -- programming. module Generics.Pointless.Combinators data Ann a vnn :: a -> Ann a -- | The bottom value for any type. It is many times used just for type -- annotations. _L :: a -- | The final object. The only possible value of type One is -- _L. data One -- | Creates a point to the terminal object. bang :: a -> One -- | Converts elements into points. pnt :: a -> One -> a -- | The infix split combinator. (/\) :: (a -> b) -> (a -> c) -> a -> (b, c) (><) :: (a -> b) -> (c -> d) -> (a, c) -> (b, d) -- | Injects a value to the left of a sum. inl :: a -> Either a b -- | Injects a value to the right of a sum. inr :: b -> Either a b -- | The infix either combinator. (\/) :: (b -> a) -> (c -> a) -> Either b c -> a -- | The infix sum combinator. (-|-) :: (a -> b) -> (c -> d) -> Either a c -> Either b d -- | Alias for the infix sum combinator. (<>) :: (a -> b) -> (c -> d) -> Either a c -> Either b d -- | The application combinator. app :: (a -> b, a) -> b -- | The left exponentiation combinator. lexp :: (a -> b) -> (b -> c) -> (a -> c) -- | The right exponentiation combinator. rexp :: (b -> c) -> (a -> b) -> (a -> c) -- | The infix combinator for a constant point. (!) :: a -> b -> a -- | Guard combinator that operates on Haskell booleans. grd :: (a -> Bool) -> a -> Either a a -- | Infix guard combinator that simulates the postfix syntax. (?) :: (a -> Bool) -> a -> Either a a (??) :: (a -> Either One One) -> a -> Either a a -- | The uncurried split combinator. split :: (a -> b, a -> c) -> (a -> (b, c)) -- | The uncurried either combinator. eithr :: (a -> c, b -> c) -> Either a b -> c -- | The uncurried composition combinator. comp :: (b -> c, a -> b) -> (a -> c) -- | Binary or of boolean functions. orf :: (a -> Bool, a -> Bool) -> (a -> Bool) -- | Binary and of boolean functions. andf :: (a -> Bool, a -> Bool) -> (a -> Bool) -- | Binary or point-free combinator. or :: (Bool, Bool) -> Bool -- | Binary and point-free combinator. and :: (Bool, Bool) -> Bool -- | Binary equality point-free combinator. eq :: Eq a => (a, a) -> Bool -- | Binary inequality point-free combinator. neq :: Eq a => (a, a) -> Bool -- | Swap the elements of a product. swap :: (a, b) -> (b, a) -- | Swap the elements of a sum. coswap :: Either a b -> Either b a -- | Distribute products over the left of sums. distl :: (Either a b, c) -> Either (a, c) (b, c) -- | Distribute sums over the left of products. undistl :: Either (a, c) (b, c) -> (Either a b, c) -- | Distribute products over the right of sums. distr :: (c, Either a b) -> Either (c, a) (c, b) -- | Distribute sums over the right of products. undistr :: Either (c, a) (c, b) -> (c, Either a b) -- | Associate nested products to the left. assocl :: (a, (b, c)) -> ((a, b), c) -- | Associates nested products to the right. assocr :: ((a, b), c) -> (a, (b, c)) -- | Associates nested sums to the left. coassocl :: Either a (Either b c) -> Either (Either a b) c -- | Associates nested sums to the right. coassocr :: Either (Either a b) c -> Either a (Either b c) -- | Shifts the an element to the right of a nested pair. subr :: (a, (b, c)) -> (b, (a, c)) -- | Shifts the an element to the left of a nested pair. subl :: ((a, b), c) -> ((a, c), b) -- | Shifts an option to the right of a nested sum. cosubr :: Either a (Either b c) -> Either b (Either a c) -- | Shifts an option to the left of a nested sum. cosubl :: Either (Either a b) c -> Either (Either a c) b -- | The product distribution combinator distp :: ((c, d), (a, b)) -> ((c, a), (d, b)) -- | The sum distribution combinator. dists :: (Either a b, Either c d) -> Either (Either (a, c) (a, d)) (Either (b, c) (b, d)) instance Typeable One instance Eq One instance Show One instance Show (Ann a) -- | Pointless Haskell: point-free programming with recursion patterns as -- hylomorphisms -- -- This module defines data types as fixed points of functor. Pointless -- Haskell works on a view of data types as fixed points of functors, in -- the same style as the PolyP -- (http://www.cse.chalmers.se/~patrikj/poly/polyp/) library. -- Instead of using an explicit fixpoint operator, a type function is -- used to relate the data types with their equivalent functor -- representations. module Generics.Pointless.Functors -- | Identity functor. data Id x IdF :: x -> Id x unIdF :: Id x -> x -- | Constant functor. data Const t x ConsF :: t -> Const t x unConsF :: Const t x -> t -- | Sum of functors. data (:+:) g h x InlF :: (g x) -> :+: g h x InrF :: (h x) -> :+: g h x -- | Product of functors. data (:*:) g h x ProdF :: (g x) -> (h x) -> :*: g h x -- | Composition of functors. data (:@:) g h x CompF :: g (h x) -> :@: g h x unCompF :: :@: g h x -> g (h x) -- | Explicit fixpoint operator. newtype Fix f Inn :: Rep f (Fix f) -> Fix f -- | The unfolding of the fixpoint of a functor is the functor applied to -- its fixpoint. -- -- unFix is specialized with the application of Rep in -- order to subsume functor application ouT :: Fix f -> Rep f (Fix f) -- | Family of patterns functors of data types. -- -- The type function is not necessarily injective, this is, different -- data types can have the same base functor. -- -- Semantically, we can say that a = Fix f. -- | Family of functor representations. -- -- The Rep family implements the implicit coercion between the -- application of a functor and the structurally equivalent sum of -- products. -- -- Functors applied to types can be represented as sums of products. -- | A specific Show class for functor representations that -- receives a show function for recursive instances. This avoids infinite -- loops in the type inference of fixpoints. class ShowRep f showrep :: ShowRep f => Ann (Fix f) -> (x -> String) -> Rep f x -> String class ToRep f rep :: ToRep f => f x -> Rep f x fun :: ToRep f => f x -> Ann (Fix f) val :: ToRep f => f x -> Ann x unrep :: ToRep f => Ann (Fix f) -> Ann x -> Rep f x -> f x -- | Polytypic Prelude.Functor class for functor representations class Functor f :: (* -> *) fmap :: Functor f => Ann (Fix f) -> (x -> y) -> Rep f x -> Rep f y fzip :: Functor f => Ann (Fix f) -> (a -> c) -> (Rep f a, Rep f c) -> Rep f (a, c) lzip :: (a -> c) -> ([a], [c]) -> [(a, c)] -- | Short alias to express the structurally equivalent sum of products for -- some data type type F a x = Rep (PF a) x -- | Polytypic map function pmap :: Functor (PF a) => Ann a -> (x -> y) -> F a x -> F a y -- | The Mu class provides the value-level translation between data -- types and their sum of products representations class Mu a inn :: Mu a => F a a -> a out :: Mu a => a -> F a a inn' :: Mu a => Ann a -> F a a -> a out' :: Mu a => Ann a -> a -> F a a -- | In order to simplify type-level composition of functors, we can create -- fixpoint combinators that implicitely assume fixpoint application. -- -- Semantically, we can say that I = Fix -- Id. data I FixId :: I -- | Semantically, we can say that K t = Fix -- (Const t). data K a FixConst :: a -> K a unFixConst :: K a -> a -- | Semantically, we can say that Fix f :+!: Fix g = -- Fix (f :+: g). data (:+!:) a b FixSum :: F (a :+!: b) (a :+!: b) -> :+!: a b unFixSum :: :+!: a b -> F (a :+!: b) (a :+!: b) -- | Semantically, we can say that Fix f :*!: Fix g = -- Fix (f :*: g). data (:*!:) a b FixProd :: F (a :*!: b) (a :*!: b) -> :*!: a b unFixProd :: :*!: a b -> F (a :*!: b) (a :*!: b) -- | Semantically, we can say that Fix f :@!: Fix g = -- Fix (f ':@: g). data (:@!:) a b FixComp :: F (a :@!: b) (a :@!: b) -> :@!: a b unFixComp :: :@!: a b -> F (a :@!: b) (a :@!: b) nil :: One -> [a] cons :: (a, [a]) -> [a] data Nat Nat :: Int -> Nat zero :: One -> Int suck :: Int -> Int natInt :: Nat -> Int intNat :: Int -> Nat true :: One -> Bool false :: One -> Bool maybe2bool :: Maybe a -> Bool instance Typeable1 Id instance Typeable2 Const instance Typeable Nat instance Eq x => Eq (Id x) instance Show x => Show (Id x) instance Eq t => Eq (Const t x) instance Show t => Show (Const t x) instance (Eq (g x), Eq (h x)) => Eq ((:+:) g h x) instance (Show (g x), Show (h x)) => Show ((:+:) g h x) instance (Eq (g x), Eq (h x)) => Eq ((:*:) g h x) instance (Show (g x), Show (h x)) => Show ((:*:) g h x) instance Eq (g (h x)) => Eq ((:@:) g h x) instance Show (g (h x)) => Show ((:@:) g h x) instance Eq Nat instance Show Nat instance Read Nat instance Data Nat instance Mu (Maybe a) instance Mu Bool instance Mu Int instance Mu Nat instance Mu [a] instance Mu (a :@!: b) instance Mu (a :*!: b) instance Mu (a :+!: b) instance Mu (K a) instance Mu I instance Mu (Fix f) instance Functor [] instance (Functor g, Functor h) => Functor (g :@: h) instance (Functor g, Functor h) => Functor (g :@: h) instance (Functor g, Functor h) => Functor (g :*: h) instance (Functor g, Functor h) => Functor (g :*: h) instance (Functor g, Functor h) => Functor (g :+: h) instance (Functor g, Functor h) => Functor (g :+: h) instance Functor (Const t) instance Functor (Const t) instance Functor Id instance Functor Id instance (Functor f, Functor f, ToRep f, ToRep g) => ToRep (f :@: g) instance (ToRep f, ToRep g) => ToRep (f :+: g) instance (ToRep f, ToRep g) => ToRep (f :*: g) instance ToRep (Const c) instance ToRep Id instance ToRep [] instance (ShowRep f, ShowRep g) => ShowRep (f :@: g) instance (ShowRep f, ShowRep g) => ShowRep (f :+: g) instance (ShowRep f, ShowRep g) => ShowRep (f :*: g) instance Show t => ShowRep (Const t) instance ShowRep Id instance ShowRep f => Show (Fix f) instance (Typeable (g x), Typeable (h x)) => Typeable ((:@:) g h x) instance (Typeable (g x), Typeable (h x)) => Typeable ((:*:) g h x) instance (Typeable (g x), Typeable (h x)) => Typeable ((:+:) g h x) -- | Pointless Haskell: point-free programming with recursion patterns as -- hylomorphisms -- -- This module defines polymorphic data types as fixed points of -- higher-order functor. module Generics.Pointless.HFunctors -- | The type of natural transformations type :~> s v = forall a. s a -> v a -- | Identity higher-order functor newtype Functor f => HId f :: (* -> *) a IdH :: f a -> HId a unIdH :: HId a -> f a -- | Constant higher-order functor newtype HConst c f :: (* -> *) a ConsH :: c -> HConst c a unConsH :: HConst c a -> c -- | Parameter higher-order functor newtype HParam f :: (* -> *) a HPar :: a -> HParam a unParH :: HParam a -> a newtype Functor g => HFun g :: (* -> *) f :: (* -> *) a HFun :: g a -> HFun a unFunH :: HFun a -> g a -- | Sum higher-order functor data (:+~:) g :: ((* -> *) -> * -> *) h :: ((* -> *) -> * -> *) f :: (* -> *) a InlH :: (g f a) -> :+~: a InrH :: (h f a) -> :+~: a -- | Product higher-order functor data (:*~:) g :: ((* -> *) -> * -> *) h :: ((* -> *) -> * -> *) f :: (* -> *) a ProdH :: (g f a) -> (h f a) -> :*~: a -- | Composition of a regular functor with an higher-order functor data (:@~:) g :: (* -> *) h :: ((* -> *) -> * -> *) f :: (* -> *) a CompH :: g (h f a) -> :@~: a unCompH :: :@~: a -> g (h f a) -- | The fixpoint of an higher-order functor is a regular functor newtype HFix f :: ((* -> *) -> * -> *) a HInn :: (HRep f (HFix f)) a -> HFix a hOut :: HFix a -> (HRep f (HFix f)) a -- | Annotations of higher-order functors, only to provide type-level -- information to the compiler data AnnH f :: ((* -> *) -> * -> *) type H t a = HRep (HF t) a class Hu t :: (* -> *) hinn :: Hu t => (H t t) a -> t a hout :: Hu t => t a -> (H t t) a -- | Polymorphic monoid class class FMonoid f fzero :: FMonoid f => f a fplus :: FMonoid f => f a -> f a -> f a class HFoldable f reduce :: (HFoldable f, FMonoid g) => AnnH f -> (HRep f g) :~> g reduce' :: (HFoldable f, FMonoid g) => AnnH f -> Ann (Fix g) -> (HRep f g) :~> g instance (HFoldable f, HFoldable g) => HFoldable (f :*~: g) instance (HFoldable f, HFoldable g) => HFoldable (f :+~: g) instance HFoldable (HFun g) instance HFoldable HParam instance HFoldable (HConst a) instance HFoldable HId instance FMonoid [] instance FMonoid f => FMonoid (f :@: g) instance (FMonoid f, FMonoid g) => FMonoid (f :*: g) instance Hu (HFix f) instance Hu [] -- | Pointless Haskell: point-free programming with recursion patterns as -- hylomorphisms -- -- This module defines a class of representable functors. module Generics.Pointless.Fctrable -- | Functor GADT for polytypic recursive functions. At the moment it does -- not rely on a Typeable instance for constants. data Fctr f :: (* -> *) I :: Fctr Id K :: Fctr (Const c) L :: Fctr [] (:*!:) :: Fctr f -> Fctr g -> Fctr (f :*: g) (:+!:) :: Fctr f -> Fctr g -> Fctr (f :+: g) (:@!:) :: Fctr f -> Fctr g -> Fctr (f :@: g) -- | Class of representable functors. class Functor f => Fctrable f :: (* -> *) fctr :: Fctrable f => Fctr f -- | The fixpoint of a representable functor. fixF :: Fctr f -> Fix f -- | The representation of the fixpoint of a representable functor. fctrF :: Fctrable f => Fix f -> Fctr f instance (Functor f, Fctrable f, Functor g, Fctrable g) => Fctrable (f :@: g) instance (Functor f, Fctrable f, Functor g, Fctrable g) => Fctrable (f :+: g) instance (Functor f, Fctrable f, Functor g, Fctrable g) => Fctrable (f :*: g) instance Fctrable [] instance Fctrable (Const c) instance Fctrable Id -- | Pointless Haskell: point-free programming with recursion patterns as -- hylomorphisms -- -- This module defines recursion patterns as hylomorphisms. -- -- Recursion patterns can be seen as high-order functions that -- encapsulate typical forms of recursion. The hylomorphism recursion -- pattern was first defined in -- http://research.microsoft.com/~emeijer/Papers/CWIReport.pdf, -- along with its relation with derived more specific recursion patterns -- such as catamorphisms, anamorphisms and paramorphisms. -- -- The seminal paper that introduced point-free programming and defined -- many of the laws for catamorphisms and anamorphisms can be found in -- http://eprints.eemcs.utwente.nl/7281/01/db-utwente-40501F46.pdf. -- -- More complex and exotic recursion patterns have been discovered later, -- such as accumulations, apomorphisms, zygomorphisms, histomorphisms, -- futumorphisms, dynamorphisms or chronomorphisms. module Generics.Pointless.RecursionPatterns -- | Definition of an hylomorphism hylo :: Functor (PF b) => Ann b -> (F b c -> c) -> (a -> F b a) -> a -> c -- | Definition of a catamorphism as an hylomorphism. -- -- Catamorphisms model the fundamental pattern of iteration, where -- constructors for recursive datatypes are repeatedly consumed by -- arbitrary functions. They are usually called folds. cata :: (Mu a, Functor (PF a)) => Ann a -> (F a b -> b) -> a -> b -- | Recursive definition of a catamorphism. cataRec :: (Mu a, Functor (PF a)) => Ann a -> (F a b -> b) -> a -> b -- | Definition of an anamorphism as an hylomorphism. -- -- Anamorphisms resembles the dual of iteration and, hence, dene the -- inverse of catamorphisms. Instead of consuming recursive types, they -- produce values of those types. ana :: (Mu b, Functor (PF b)) => Ann b -> (a -> F b a) -> a -> b -- | Recursive definition of an anamorphism. anaRec :: (Mu b, Functor (PF b)) => Ann b -> (a -> F b a) -> a -> b -- | The functor of the intermediate type of a paramorphism is the functor -- of the consumed type a extended with an extra annotation to -- itself in recursive definitions. type Para a = a :@!: (I :*!: K a) -- | Definition of a paramorphism. -- -- Paramorphisms supply the gene of a catamorphism with a recursively -- computed copy of the input. -- -- The first introduction to paramorphisms is reported in -- http://www.cs.uu.nl/research/techreps/repo/CS-1990/1990-04.pdf. para :: (Mu a, Functor (PF a)) => Ann a -> (F a (b, a) -> b) -> a -> b -- | Recursive definition of a paramorphism. paraRec :: (Mu a, Functor (PF a)) => Ann a -> (F a (b, a) -> b) -> a -> b -- | The functor of the intermediate type of an apomorphism is the functor -- of the generated type b with an alternative annotation to -- itself in recursive definitions. type Apo b = b :@!: (I :+!: K b) -- | Definition of an apomorphism as an hylomorphism. -- -- Apomorphisms are the dual recursion patterns of paramorphisms, and -- therefore they can express functions defined by primitive corecursion. -- -- They were introduced independently in -- http://www.cs.ut.ee/~varmo/papers/nwpt97.ps.gz and Program -- Construction and Generation Based on Recursive Types, MSc thesis. apo :: (Mu b, Functor (PF b)) => Ann b -> (a -> F b (Either a b)) -> a -> b -- | Recursive definition of an apomorphism. apoRec :: (Mu b, Functor (PF b)) => Ann b -> (a -> F b (Either a b)) -> a -> b -- | In zygomorphisms we extend the recursive occurences in the base -- functor functor of type a with an extra annotation -- b. type Zygo a b = a :@!: (I :*!: K b) -- | Definition of a zygomorphism as an hylomorphism. -- -- Zygomorphisms were introduced in -- http://dissertations.ub.rug.nl/faculties/science/1990/g.r.malcolm/. -- -- They can be seen as the asymmetric form of mutual iteration, where -- both a data consumer and an auxiliary function are defined -- (http://www.fing.edu.uy/~pardo/papers/njc01.ps.gz). zygo :: (Mu a, Functor (PF a), (F a (a, b)) ~ (F (Zygo a b) a)) => Ann a -> (F a b -> b) -> (F (Zygo a b) b -> b) -> a -> b -- | In accumulations we add an extra annotation b to the base -- functor of type a. type Accum a b = a :*!: K b -- | Definition of an accumulation as an hylomorphism. -- -- Accumulations http://www.fing.edu.uy/~pardo/papers/wcgp02.ps.gz -- are binary functions that use the second parameter to store -- intermediate results. -- -- The so called accumulation technique is tipically used in -- functional programming to derive efficient implementations of some -- recursive functions. accum :: (Mu a, Functor (PF a)) => Ann a -> (F (Accum a b) c -> c) -> ((F a a, b) -> F a (a, b)) -> (a, b) -> c -- | In histomorphisms we add an extra annotation c to the base -- functor of type a. type Histo a c = K c :*!: a -- | Definition of an histomorphism as an hylomorphism (as long as the -- catamorphism is defined as an hylomorphism). -- -- Histomorphisms (http://cs.ioc.ee/~tarmo/papers/inf.ps.gz) -- capture the powerfull schemes of course-of-value iteration, and differ -- from catamorphisms for being able to apply the gene function at a -- deeper depth of recursion. In other words, they allow to reuse sub-sub -- constructor results. histo :: (Mu a, Functor (PF a)) => Ann a -> (F a (Histo a c) -> c) -> a -> c -- | The combinator outl unpacks the functor of an histomorphism and -- selects the annotation. outl :: Histo a c -> c -- | The combinator outr unpacks the functor of an histomorphism and -- discards the annotation. outr :: Histo a c -> F a (Histo a c) -- | In futumorphisms we add an alternative annotation c to the -- base functor of type b. type Futu b c = K c :+!: b -- | Definition of a futumorphism as an hylomorphism (as long as the -- anamorphism is defined as an hylomorphism). -- -- Futumorphisms are the dual of histomorphisms and are proposed as -- 'cocourse-of-argument' coiterators by their creators -- (http://cs.ioc.ee/~tarmo/papers/inf.ps.gz). -- -- In the same fashion as histomorphisms, it allows to seed the gene with -- multiple levels of depth instead of having to do 'all at once' with an -- anamorphism. futu :: (Mu b, Functor (PF b)) => Ann b -> (a -> F b (Futu b a)) -> a -> b -- | The combinator innl packs the functor of a futumorphism from -- the base functor. innl :: c -> Futu b c -- | The combinator innr packs the functor of an futumorphism from -- an annotation. innr :: F b (Futu b c) -> Futu b c -- | Definition of a dynamorphism as an hylomorphisms. -- -- Dynamorphisms -- (http://math.ut.ee/~eugene/kabanov-vene-mpc-06.pdf) are a more -- general form of histomorphisms for capturing dynaming programming -- constructions. -- -- Instead of following the recursion pattern of the input via structural -- recursion (as in histomorphisms), dynamorphisms allow us to reuse the -- annotated structure in a bottom-up approach and avoiding rebuilding it -- every time an annotation is needed, what provides a more efficient -- dynamic algorithm. dyna :: (Mu b, Functor (PF b)) => Ann b -> (F b (Histo b c) -> c) -> (a -> F b a) -> a -> c -- | Definition of a chronomorphism as an hylomorphism. -- -- This recursion pattern subsumes histomorphisms, futumorphisms and -- dynamorphisms and can be seen as the natural hylomorphism -- generalization from composing an histomorphism after a futumorphism. -- Therefore, chronomorphisms can 'look back' when consuming a type and -- 'jump forward' when generating one, via it's fold/unfold operations, -- respectively. -- -- The notion of chronomorphism is a recent recursion pattern (at least -- known as such). The first and single reference available is -- http://comonad.com/reader/2008/time-for-chronomorphisms/. chrono :: (Mu c, Functor (PF c)) => Ann c -> (F c (Histo c b) -> b) -> (a -> F c (Futu c a)) -> a -> b -- | The Fixpoint combinator as an hylomorphism. -- -- fix is a fixpoint combinator if fix = app -- . (id /\ fix). -- -- After expanding the denitions of ., /\ and app -- we see that this corresponds to the expected pointwise equation -- fix f = f (fix f). fix :: (a -> a) -> a -- | Pointless Haskell: point-free programming with recursion patterns as -- hylomorphisms -- -- This module defines generic GHood observations for user-defined data -- types. module Generics.Pointless.Observe.Functors -- | Class for mapping observations over functor representations. class FunctorO f functorOf :: FunctorO f => Ann (Fix f) -> String watch :: FunctorO f => Ann (Fix f) -> Ann x -> Rep f x -> String fmapO :: FunctorO f => Ann (Fix f) -> (x -> ObserverM y) -> Rep f x -> ObserverM (Rep f y) -- | Polytypic mapping of observations. omap :: FunctorO (PF a) => Ann a -> (x -> ObserverM y) -> F a x -> ObserverM (F a y) instance (Functor f, FunctorO f) => Observable (Fix f) instance (FunctorO (PF a), FunctorO (PF b)) => Observable (a :@!: b) instance (FunctorO (PF a), FunctorO (PF b)) => Observable (a :*!: b) instance (FunctorO (PF a), FunctorO (PF b)) => Observable (a :+!: b) instance (Typeable a, Observable a) => Observable (K a) instance Observable I instance Observable One instance (FunctorO g, FunctorO h) => FunctorO (g :@: h) instance (FunctorO f, FunctorO g) => FunctorO (f :*: g) instance (FunctorO f, FunctorO g) => FunctorO (f :+: g) instance (Typeable a, Observable a) => FunctorO (Const a) instance FunctorO Id -- | Pointless Haskell: point-free programming with recursion patterns as -- hylomorphisms -- -- This module redefines recursion patterns with support for GHood -- observation of intermediate data structures. module Generics.Pointless.Observe.RecursionPatterns -- | Redefinition of hylomorphisms with observation of the intermediate -- data type. hyloO :: (Mu b, Functor (PF b), FunctorO (PF b)) => Ann b -> (F b c -> c) -> (a -> F b a) -> a -> c -- | Redefinition of catamorphisms as observable hylomorphisms. cataO :: (Mu a, Functor (PF a), FunctorO (PF a)) => Ann a -> (F a b -> b) -> a -> b -- | Redefinition of anamorphisms as observable hylomorphisms. anaO :: (Mu b, Functor (PF b), FunctorO (PF b)) => Ann b -> (a -> F b a) -> a -> b -- | Redefinition of paramorphisms as observable hylomorphisms. paraO :: (Mu a, Functor (PF a), FunctorO (PF a), Observable a, Typeable a) => Ann a -> (F a (b, a) -> b) -> a -> b -- | Redefinition of apomorphisms as observable hylomorphisms. apoO :: (Mu b, Functor (PF b), FunctorO (PF b), Observable b, Typeable b) => Ann b -> (a -> F b (Either a b)) -> a -> b -- | Redefinition of zygomorphisms as observable hylomorphisms. zygoO :: (Mu a, Functor (PF a), FunctorO (PF a), Observable b, Typeable b, (F a (a, b)) ~ (F (Zygo a b) a)) => Ann a -> (F a b -> b) -> (F (Zygo a b) b -> b) -> a -> b -- | Redefinition of accumulations as observable hylomorphisms. accumO :: (Mu a, Functor (PF d), FunctorO (PF d), Observable b, Typeable b) => Ann d -> ((F a a, b) -> F d (a, b)) -> (F (Accum d b) c -> c) -> (a, b) -> c -- | Redefinition of histomorphisms as observable hylomorphisms. histoO :: (Mu a, Functor (PF a), FunctorO (PF a), Observable a) => Ann a -> (F a (Histo a c) -> c) -> a -> c -- | Redefinition of futumorphisms as observable hylomorphisms. futuO :: (Mu b, Functor (PF b), FunctorO (PF b), Observable b) => Ann b -> (a -> F b (Futu b a)) -> a -> b -- | Redefinition of dynamorphisms as observable hylomorphisms. dynaO :: (Mu b, Functor (PF b), FunctorO (PF b), Observable b) => Ann b -> (F b (Histo b c) -> c) -> (a -> F b a) -> a -> c -- | Redefinition of chronomorphisms as observable hylomorphisms. chronoO :: (Mu c, Functor (PF c), FunctorO (PF c)) => Ann c -> (F c (Histo c b) -> b) -> (a -> F c (Futu c a)) -> a -> b -- | Pointless Haskell: point-free programming with recursion patterns as -- hylomorphisms -- -- This module provides examples, examples and more examples. module Generics.Pointless.Examples.Examples -- | Pre-defined algebraic addition. add :: (Int, Int) -> Int -- | Definition of algebraic addition as an anamorphism in the point-wise -- style. addAnaPW :: (Int, Int) -> Int -- | Defition of algebraic addition as an anamorphism. addAna :: (Int, Int) -> Int -- | The fixpoint of the functor that is either a constant or defined -- recursively. type From a = K a :+!: I -- | Definition of algebraic addition as an hylomorphism. addHylo :: (Int, Int) -> Int -- | Definition of algebraic addition as an accumulation. addAccum :: (Int, Int) -> Int addApoPW :: (Int, Int) -> Int -- | Definition of algebraic addition as an apomorphism. addApo :: (Int, Int) -> Int -- | Pre-defined algebraic product. prod :: (Int, Int) -> Int -- | Definition of algebraic product as an hylomorphism prodHylo :: (Int, Int) -> Int -- | Pre-defined 'greater than' comparison. gt :: Ord a => (a, a) -> Bool -- | Definition of 'greater than' as an hylomorphism. gtHylo :: (Int, Int) -> Bool -- | Native recursive definition of the factorial function. fact :: Int -> Int -- | Recursive definition of the factorial function in the point-free -- style. factPF :: Int -> Int -- | Recursive definition of the factorial function in the point-free style -- with structural recursion. factPF' :: Int -> Int -- | Definition of the factorial function as an hylomorphism. factHylo :: Int -> Int -- | Definition of the factorial function as a paramorphism. factPara :: Int -> Int -- | Definition of the factorial function as a zygomorphism. factZygo :: Int -> Int -- | Native recursive definition of the fibonacci function. fib :: Int -> Int -- | Recursive definition of the fibonacci function in the point-free -- style. fibPF :: Int -> Int -- | Recursive definition of the fibonacci function in the point-free style -- with structural recursion. fibPF' :: Int -> Int -- | The fixpoint of the functor for a binary shape tree. type BSTree = K One :+!: (K One :+!: (I :*!: I)) -- | Definition of the fibonacci function as an hylomorphism. fibHylo :: Int -> Int -- | Definition of the fibonacci function as an histomorphism. fibHisto :: Int -> Int -- | Definition of the fibonacci function as a dynamorphism. fibDyna :: Int -> Int -- | Native recursive definition for the binary partitions of a number. -- -- The number of binary partitions for a number n is the number of unique -- ways to partition this number (ignoring the order) into powers of 2. | -- Definition of the binary partitioning of a number as an hylomorphism. bp :: Int -> Int -- | The fixpoint of the functor representing trees with maximal branching -- factor of two. type BTree = K One :+!: (I :+!: (I :*!: I)) -- | Definition of the binary partitioning of a number as an hylomorphism. bpHylo :: Int -> Int -- | Definition of the binary partitioning of a number as a dynamorphism. bpDyna :: Int -> Int -- | Recursive definition of the average of a set of integers. average :: [Int] -> Int -- | Definition of the average of a set of integers as a catamorphism. averageCata :: [Int] -> Int -- | Pre-defined wrapping of an element into a list. wrap :: a -> [a] -- | Definition of wrapping in the point-free style. wrapPF :: a -> [a] -- | Definition of the tail of a list as a total function. tail :: [a] -> [a] -- | Definition of the tail of a list in the point-free style. tailPF :: [a] -> [a] -- | Definition of the tail of a list as an anamorphism. tailCata :: [a] -> [a] -- | Definition of the tail of a list as a paramorphism. tailPara :: [a] -> [a] -- | Native recursion definition of list length. length :: [a] -> Int -- | Recursive definition of list length in the point-free style. lengthPF :: [a] -> Int -- | Recursive definition of list length in the point-free style with -- structural recursion. lengthPF' :: [a] -> Int -- | Definition of list length as an hylomorphism. lengthHylo :: [a] -> Int -- | Definition of list length as an anamorphism. lengthAna :: [a] -> Int -- | Definition of list length as a catamorphism. lengthCata :: [a] -> Int -- | Native recursive definition of list filtering. filter :: (a -> Bool) -> [a] -> [a] -- | Definition of list filtering as an catamorphism. filterCata :: (a -> Bool) -> [a] -> [a] -- | Generation of infinite lists as an anamorphism. repeatAna :: a -> [a] -- | Finite replication of an element as an anamorphism. replicateAna :: (Int, a) -> [a] -- | Generation of a downwards list as an anamorphism. downtoAna :: Int -> [Int] -- | Ordered list insertion as an apomorphism. insertApo :: Ord a => (a, [a]) -> [a] -- | Ordered list insertion as a paramorphism. insertPara :: Ord a => (a, [a]) -> [a] -- | Append an element to the end of a list as an hylomorphism. snoc :: (a, [a]) -> [a] -- | Append an element to the end of a list as an apomorphism. snocApo :: (a, [a]) -> [a] -- | Creates a bubble from a list. Used in the bubble sort algorithm. bubble :: Ord a => [a] -> Either One (a, [a]) -- | Extraction of a number of elements from a list as an anamorphism. takeAna :: (Int, [a]) -> [a] -- | Native recursive definition for partitioning a list at a specified -- element. partition :: Ord a => (a, [a]) -> ([a], [a]) -- | Definition for partitioning a list at a specified element as an -- hylomorphism. partitionHylo :: Ord a => (a, [a]) -> ([a], [a]) -- | Incremental summation as a catamorphism. isum :: [Int] -> [Int] -- | Incrementation the elements of a list by a specified value as a -- catamorphism. fisum :: [Int] -> Int -> [Int] data Some a Wrap :: a -> Some a Insert :: a -> (Some a) -> Some a -- | Incrementation the elements of a list by a specified value as an -- accumulation. The result is always a non-empty list isumsAccum :: ([Int], Int) -> Some Int isumsAna :: ([Int], Int) -> Some Int -- | Definition of list mapping as a catamorphism. mapCata :: [a] -> (a -> b) -> [b] -- | Definition of list reversion as a catamorphism. reverseCata :: [a] -> [a] -- | Linear version of reverse using accumulations reverseAccum' :: ([a], [a]) -> [a] reverseHylo :: ([a], [a]) -> [a] -- | Definition of the quicksort algorithm as an hylomorphism. qsort :: Ord a => [a] -> [a] -- | Definition of the bubble sort algorithm as an anamorphism. bsort :: Ord a => [a] -> [a] -- | Definition of the insertion sort algorithm as a catamorphism. isort :: Ord a => [a] -> [a] msplit :: [a] -> ([a], [a]) msort :: Ord a => [a] -> [a] -- | Definition of the heap sort algorithm as an hylomorphism. hsort :: Ord a => [a] -> [a] hsplit :: Ord a => [a] -> (a, ([a], [a])) -- | Malcolm downwards accumulations on lists. malcolm :: ((b, a) -> a) -> a -> [b] -> [a] -- | Malcom downwards accumulations on lists as an anamorphism. malcolmAna :: ((b, a) -> a) -> a -> [b] -> [a] -- | Uncurried version of Malcom downwards accumulations on lists as an -- anamorphism. malcolmAna' :: ((b, a) -> a) -> ([b], a) -> [a] -- | Definition of the zip for lists of pairs as an anamorphism. zipAna :: ([a], [b]) -> [(a, b)] -- | Definition of the subsequences of a list as a catamorphism. subsequences :: Eq a => [a] -> [[a]] -- | Pre-defined list concatenation. cat :: ([a], [a]) -> [a] -- | List concatenation as a catamorphism. catCata :: [a] -> [a] -> [a] -- | The fixpoint of the list functor with a specific terminal element. type NeList a b = K a :+!: (K b :*!: I) -- | List concatenation as an hylomorphism. catHylo :: ([a], [a]) -> [a] -- | Native recursive definition of lists-of-lists concatenation. concat :: [[a]] -> [a] -- | Definition of lists-of-lists concatenation as an anamorphism. concatCata :: [[a]] -> [a] -- | Sorted concatenation of two lists as an hylomorphism. merge :: Ord a => ([a], [a]) -> [a] -- | Definition of inter addition as a catamorphism. sumCata :: [Int] -> Int -- | Native recursive definition of integer multiplication. mult :: [Int] -> Int -- | Definition of integer multiplication as a catamorphism. multCata :: [Int] -> Int sorted :: Ord a => [a] -> Bool -- | Native recursive definition of the edit distance algorithm. -- -- Edit distance is a classical dynamic programming algorithm that -- calculates a measure of distance or dierence between lists with -- comparable elements. editdist :: Eq a => ([a], [a]) -> Int -- | The fixpoint of the functor that represents a virtual matrix used to -- accumulate and look up values for the edit distance algorithm. -- -- Since matrixes are not inductive types, a walk-through of a matrix is -- used, consisting in a list of values from the matrix ordered -- predictability. -- -- For a more detailed explanation, please refer to -- http://math.ut.ee/~eugene/kabanov-vene-mpc-06.pdf. type EditDist a = K [a] :+!: ((K a :*!: K a) :*!: (I :*!: (I :*!: I))) type EditDistL a = (K [a] :*!: K [a]) :*!: (K One :+!: I) -- | The edit distance algorithm as an hylomorphism. editdistHylo :: Eq a => ([a], [a]) -> Int -- | The edit distance algorithm as a dynamorphism. editDistDyna :: Eq a => ([a], [a]) -> Int -- | The fixpoint of the functor of streams. type Stream a = K a :*!: I -- | Stream head. headS :: Stream a -> a -- | Stream tail. tailS :: Stream a -> Stream a -- | Definition of a stream sequence generator as an anamorphism. generate :: Int -> Stream Int -- | Identity o streams as an anamorphism. idStream :: Stream a -> Stream a -- | Mapping over streams as an anamorphism. mapStream :: (a -> b) -> Stream a -> Stream b -- | Malcolm downwards accumulations on streams. malcolmS :: ((b, a) -> a) -> a -> Stream b -> Stream a -- | Malcom downwards accumulations on streams as an anamorphism. malcolmSAna :: ((b, a) -> a) -> a -> Stream b -> Stream a -- | Uncurried version of Malcom downwards accumulations on streams as an -- anamorphism. malcolmSAna' :: ((b, a) -> a) -> (Stream b, a) -> Stream a -- | Promotes streams elements to streams of singleton elements. inits :: Stream a -> Stream [a] -- | Definition of parwise exchange on streams as a futumorphism. exchFutu :: Stream a -> Stream a -- | Datatype declaration of a binary tree. data Tree a Empty :: Tree a Node :: a -> (Tree a) -> (Tree a) -> Tree a -- | Counting the number of leaves in a binary tree as a catamorphism. nleaves :: Tree a -> Int -- | Counting the number of nodes in a binary tree as a catamorphism. nnodes :: Tree a -> Int -- | Generation of a binary tree with a specified height as an anamorphism. genTree :: Int -> Tree Int -- | The preorder traversal on binary trees as a catamorphism. preTree :: Tree a -> [a] -- | The postorder traversal on binary trees as a catamorphism. postTree :: Tree a -> [a] -- | Datatype declaration of a leaf tree. data LTree a Leaf :: a -> LTree a Branch :: (LTree a) -> (LTree a) -> LTree a -- | Extract the leaves of a leaf tree as a catamorphism. leaves :: LTree a -> [a] -- | Generation of a leaft tree of a specified height as an anamorphism. genLTree :: Int -> LTree Int -- | Calculate the height of a leaf tree as a catamorphism. height :: LTree a -> Int -- | Datatype declaration of a rose tree. data Rose a Forest :: a -> [Rose a] -> Rose a preRose :: Rose a -> [a] -- | The postorder traversal on rose trees as a catamorphism. postRose :: Rose a -> [a] -- | Generation of a rose tree of a specified height as an anamorphism. genRose :: Int -> Rose Int instance Eq a => Eq (Some a) instance Show a => Show (Some a) instance Show a => Show (Tree a) instance Eq a => Eq (LTree a) instance Show a => Show (LTree a) instance Show a => Show (Rose a) instance Mu (Rose a) instance Mu (LTree a) instance Mu (Tree a) instance Mu (Some a) -- | Pointless Haskell: point-free programming with recursion patterns as -- hylomorphisms -- -- This module provides the same examples, but with support for GHood -- observations. module Generics.Pointless.Examples.Observe -- | Definition of the observable length function as an hylomorphism. lengthHyloO :: Observable a => [a] -> Int -- | Definition of the observable length function as an anamorphism. lengthAnaO :: Observable a => [a] -> Int -- | Definition of the observable length function as a catamorphism. lengthCataO :: (Typeable a, Observable a) => [a] -> Int -- | Definition of the observable factorial function as an hylomorphism. factHyloO :: Int -> Int -- | Definition of the observable factorial function as a paramorphism. factParaO :: Int -> Int -- | Definition of the observable factorial function as a zygomorphism. factZygoO :: Int -> Int -- | Definition of the observable fibonacci function as an hylomorphism. fibHyloO :: Int -> Int -- | Definition of the observable fibonacci function as an histomorphism. fibHistoO :: Int -> Int -- | Definition of the observable fibonacci function as a dynamorphism. fibDynaO :: Int -> Int -- | Definition of the observable quicksort function as an hylomorphism. qsortHyloO :: (Typeable a, Observable a, Ord a) => [a] -> [a] -- | Definition of the observable tail function as a paramorphism. tailParaO :: (Typeable a, Observable a) => [a] -> [a] -- | Definition of the observable add function as an accumulation. addAccumO :: (Int, Int) -> Int -- | Pointless Haskell: point-free programming with recursion patterns as -- hylomorphisms -- -- This module lifts many standard combinators used for point-free -- programming to combinators over monads. module Generics.Pointless.MonadCombinators -- | The left-to-right monadic binding combinator. (<<=) :: Monad m => (a -> m b) -> m a -> m b -- | Higher-order monadic binding. bind :: Monad m => (a -> m b, m a) -> m b -- | The monadic left exponentiation combinator. mlexp :: Monad m => (a -> m b) -> (b -> m c) -> (a -> m c) -- | The monadic right exponentiation combinator. mrexp :: Monad m => (b -> m c) -> (a -> m b) -> (a -> m c) -- | The monadic sum combinator. (-||-) :: Monad m => (a -> m b) -> (c -> m d) -> (Either a c -> m (Either b d)) -- | The strength combinator for strong monads. In Haskell, every monad is -- a strong monad: -- http://comonad.com/reader/2008/deriving-strength-from-laziness/. mstrength :: Monad m => (b, m a) -> m (b, a) -- | The monadic fusion combinator. Performs left-to-right distribution of -- a strong monad over a product. mfuse :: Monad m => (m a, m b) -> m (a, b) -- | The monadic split combinator. (/|\) :: Monad m => (a -> m b) -> (a -> m c) -> a -> m (b, c) -- | The monadic product combinator. (>|<) :: Monad m => (a -> m c) -> (b -> m d) -> (a, b) -> m (c, d) -- | Pointless Haskell: point-free programming with recursion patterns as -- hylomorphisms -- -- This module defines polymorphic data types as fixed points of -- bifunctor. Pointless Haskell works on a view of data types as fixed -- points of functors, in the same style as the PolyP -- (http://www.cse.chalmers.se/~patrikj/poly/polyp/) library. -- Instead of using an explicit fixpoint operator, a type function is -- used to relate the data types with their equivalent functor -- representations. module Generics.Pointless.Bifunctors newtype BId a x BId :: x -> BId a x unBId :: BId a x -> x newtype BConst t a x BConst :: t -> BConst t a x unBConst :: BConst t a x -> t newtype BPar a x Par :: a -> BPar a x unPar :: BPar a x -> a data (:+|) g h a x BInl :: (g a x) -> :+| g h a x BInr :: (h a x) -> :+| g h a x data (:*|) g h a x BProd :: (g a x) -> (h a x) -> :*| g h a x newtype (:@|) g h a x BComp :: g a (h a x) -> :@| g h a x unBComp :: :@| g h a x -> g a (h a x) newtype BFix f BFix :: f (BFix f) (BFix f) -> BFix f unBFix :: BFix f -> f (BFix f) (BFix f) -- | The polytypic bifunctor zipping combinator. Just maps over the -- polymorphic parameter. To map over the recursive parameter we can use -- fzip. class Bifunctor f :: (* -> * -> *) bmap :: Bifunctor f => Ann (BFix f) -> (a -> b) -> (x -> y) -> Rep (BRep f a) x -> Rep (BRep f b) y bzip :: Bifunctor f => Ann x -> Ann (BFix f) -> (a -> c) -> (Rep (BRep f a) x, Rep (BRep f c) x) -> Rep (BRep f (a, c)) x type B d a x = Rep (BRep (BF d) a) x class Bimu d binn :: Bimu d => B d a (d a) -> d a bout :: Bimu d => d a -> B d a (d a) pbmap :: Bifunctor (BF d) => Ann (d a) -> (a -> b) -> (x -> y) -> B d a x -> B d b y data BI x FixBId :: BI x data BK a x FixBConst :: a -> BK a x unFixBConst :: BK a x -> a data (:+!|) a :: (* -> *) b :: (* -> *) x FixBSum :: B (a :+!| b) x ((a :+!| b) x) -> :+!| x unFixBSum :: :+!| x -> B (a :+!| b) x ((a :+!| b) x) data (:*!|) a :: (* -> *) b :: (* -> *) x FixBProd :: B (a :*!| b) x ((a :*!| b) x) -> :*!| x unFixBProd :: :*!| x -> B (a :*!| b) x ((a :*!| b) x) data (:@!|) a :: (* -> *) b :: (* -> *) x FixBComp :: B (a :@!| b) x ((a :@!| b) x) -> :@!| x unFixBComp :: :@!| x -> B (a :@!| b) x ((a :@!| b) x) instance Bimu [] instance Bimu (a :@!| b) instance Bimu (a :*!| b) instance Bimu (a :+!| b) instance Bimu (BK a) instance Bimu BI instance (Bifunctor g, Bifunctor h) => Bifunctor (g :@| h) instance (Bifunctor g, Bifunctor h) => Bifunctor (g :*| h) instance (Bifunctor g, Bifunctor h) => Bifunctor (g :+| h) instance Bifunctor BPar instance Bifunctor (BConst t) instance Bifunctor BId -- | Pointless Haskell: point-free programming with recursion patterns as -- hylomorphisms -- -- This module defines a class of representable bifunctors. module Generics.Pointless.Bifctrable -- | Functor GADT for polytypic recursive bifunctions. At the moment it -- does not rely on a Typeable instance for constants. data Bifctr f :: (* -> * -> *) BI :: Bifctr BId BK :: Bifctr (BConst c) BP :: Bifctr BPar (:*!|) :: Bifctr f -> Bifctr g -> Bifctr (f :*| g) (:+!|) :: Bifctr f -> Bifctr g -> Bifctr (f :+| g) (:@!|) :: Bifctr f -> Bifctr g -> Bifctr (f :@| g) -- | Class of representable bifunctors. class Bifunctor f => Bifctrable f :: (* -> * -> *) bctr :: Bifctrable f => Bifctr f -- | The fixpoint of a representable bifunctor. fixB :: Bifctr f -> BFix f -- | The representation of the fixpoint of a representable functor. fctrB :: Bifctrable f => BFix f -> Bifctr f instance (Bifunctor f, Bifctrable f, Bifunctor g, Bifctrable g) => Bifctrable (f :+| g) instance (Bifunctor f, Bifctrable f, Bifunctor g, Bifctrable g) => Bifctrable (f :*| g) instance Bifctrable BPar instance Bifctrable (BConst c) instance Bifctrable BId