Safe Haskell | None |
---|---|
Language | Haskell2010 |
A modest replacement for the basic machinery in Compdata.
Differences and limitations
Deriving of type classes for base functors
Compdata's macros for deriving are replaced by similar macros from
deriving-compat. See
the documentation for defaultEqualF
and similar functions in the same
section.
Co-products and injections
Compdata and Fixplate use different names for equivalent things. For this reason, we export type and pattern synonyms to make the interface as similar to Compdata's as possible.
Unfortunately, :+:
is defined as left-associative in Fixplate, which means
that injections will look differently. For example, consider a compound base
functor F
. Elements from :+:
G :+:
HG
are injected differently in
the two libraries:
Inr (Inl ...) -- CompdataInL
(InR
...) -- Fixplate
(Note also the difference in capitalization.)
Smart constructors
There are no TemplateHaskell macros for making smart constructors, but the operators from Data.Composition (re-exported by this module) take us a long way towards the same goal. Consider the following base functors:
data Add a = Add a a deriving (Functor) data IfThenElse a = IfThenElse a a a deriving (Functor)
Smart versions of these constructors can now be defined as follows:
(|+|) :: Add:<:
f =>Term
f ->Term
f ->Term
f (|+|) =inject
.:
Add ite :: IfThenElse:<:
f =>Term
f ->Term
f ->Term
f ->Term
f ite =inject
.:.
IfThenElse
Synopsis
- class Eq1 (f :: Type -> Type)
- class EqF (f :: Type -> Type) where
- class Show1 (f :: Type -> Type)
- class ShowF (f :: Type -> Type) where
- showsPrecF :: Show a => Int -> f a -> ShowS
- deriveEq1 :: Name -> Q [Dec]
- deriveShow1 :: Name -> Q [Dec]
- defaultEqualF :: (Eq1 f, Eq a) => f a -> f a -> Bool
- defaultShowsPrecF :: (Show1 f, Show a) => Int -> f a -> ShowS
- eqMod :: (EqF f, Functor f, Foldable f) => f a -> f b -> Maybe [(a, b)]
- type Term = Mu
- pattern Term :: f (Term f) -> Term f
- unTerm :: Term f -> f (Term f)
- type (:&:) f a = Ann f a
- pattern (:&:) :: f b -> a -> (f :&: a) b
- data ((f :: Type -> Type) :+: (g :: Type -> Type)) a
- class f :<: g where
- inject :: f :<: g => f (Term g) -> Term g
- project :: f :<: g => Term g -> Maybe (f (Term g))
- data HideInj f a
- showTerm :: (Functor f, Foldable f, ShowF (HideInj f)) => Term f -> String
- showTermU :: (Functor f, Foldable f, ShowF (HideInj f)) => Term f -> String
- drawTerm :: (Functor f, Foldable f, ShowF (HideInj f)) => Term f -> IO ()
- drawTermU :: (Functor f, Foldable f, ShowF (HideInj f)) => Term f -> IO ()
- (.:) :: (c -> d) -> (a -> b -> c) -> a -> b -> d
- (.:.) :: (d -> e) -> (a -> b -> c -> d) -> a -> b -> c -> e
- (.::) :: (d -> e) -> (a1 -> a2 -> b -> c -> d) -> a1 -> a2 -> b -> c -> e
- (.::.) :: (d -> e) -> (a1 -> a2 -> a3 -> b -> c -> d) -> a1 -> a2 -> a3 -> b -> c -> e
- (.:::) :: (d -> e) -> (a1 -> a2 -> a3 -> a4 -> b -> c -> d) -> a1 -> a2 -> a3 -> a4 -> b -> c -> e
Basic classes and operations on functors
class Eq1 (f :: Type -> Type) #
Lifting of the Eq
class to unary type constructors.
Since: base-4.9.0.0
Instances
Eq1 [] | Since: base-4.9.0.0 |
Defined in Data.Functor.Classes | |
Eq1 Maybe | Since: base-4.9.0.0 |
Eq1 Identity | Since: base-4.9.0.0 |
Eq1 Down | Since: base-4.12.0.0 |
Eq1 NonEmpty | Since: base-4.10.0.0 |
Eq1 Tree | Since: containers-0.5.9 |
Eq1 Seq | Since: containers-0.5.9 |
Eq1 Set | Since: containers-0.5.9 |
Eq a => Eq1 (Either a) | Since: base-4.9.0.0 |
Eq a => Eq1 ((,) a) | Since: base-4.9.0.0 |
Defined in Data.Functor.Classes | |
Eq1 (Proxy :: Type -> Type) | Since: base-4.9.0.0 |
Eq k => Eq1 (Map k) | Since: containers-0.5.9 |
Eq a => Eq1 (Const a :: Type -> Type) | Since: base-4.9.0.0 |
(Eq e, Eq1 m) => Eq1 (ErrorT e m) | |
class EqF (f :: Type -> Type) where #
"Functorised" versions of standard type classes. If you have your a structure functor, for example
Expr e = Kst Int | Var String | Add e e deriving (Eq,Ord,Read,Show,Functor,Foldable,Traversable)
you should make it an instance of these, so that the
fixed-point type Mu Expr
can be an instance of
Eq
, Ord
and Show
. Doing so is very easy:
instance EqF Expr where equalF = (==) instance OrdF Expr where compareF = compare instance ShowF Expr where showsPrecF = showsPrec
The Read
instance depends on whether we are using GHC or not.
The Haskell98 version is
instance ReadF Expr where readsPrecF = readsPrec
while the GHC version is
instance ReadF Expr where readPrecF = readPrec
class Show1 (f :: Type -> Type) #
Lifting of the Show
class to unary type constructors.
Since: base-4.9.0.0
Instances
Show1 [] | Since: base-4.9.0.0 |
Defined in Data.Functor.Classes | |
Show1 Maybe | Since: base-4.9.0.0 |
Show1 Identity | Since: base-4.9.0.0 |
Show1 Down | Since: base-4.12.0.0 |
Show1 NonEmpty | Since: base-4.10.0.0 |
Show1 Tree | Since: containers-0.5.9 |
Show1 Seq | Since: containers-0.5.9 |
Show1 Set | Since: containers-0.5.9 |
Show a => Show1 (Either a) | Since: base-4.9.0.0 |
Show a => Show1 ((,) a) | Since: base-4.9.0.0 |
Defined in Data.Functor.Classes | |
Show1 (Proxy :: Type -> Type) | Since: base-4.9.0.0 |
Show k => Show1 (Map k) | Since: containers-0.5.9 |
Show a => Show1 (Const a :: Type -> Type) | Since: base-4.9.0.0 |
(Show e, Show1 m) => Show1 (ErrorT e m) | |
class ShowF (f :: Type -> Type) where #
showsPrecF :: Show a => Int -> f a -> ShowS #
Instances
ShowF f => ShowF (HideInj f) Source # | |
Defined in Data.Comp.Fixplate | |
(ShowF (HideInj f), ShowF (HideInj g)) => ShowF (HideInj (f :+: g)) Source # | |
Defined in Data.Comp.Fixplate | |
(ShowF f, ShowF g) => ShowF (f :+: g) | |
Defined in Data.Generics.Fixplate.Functor | |
(ShowF f, ShowF g) => ShowF (f :*: g) | |
Defined in Data.Generics.Fixplate.Functor | |
(Show a, ShowF f) => ShowF (Ann f a) | |
Defined in Data.Generics.Fixplate.Base | |
(Show a, ShowF f) => ShowF (CoAnn f a) | |
Defined in Data.Generics.Fixplate.Base |
deriveEq1 :: Name -> Q [Dec] #
Generates an Eq1
instance declaration for the given data type or data
family instance.
deriveShow1 :: Name -> Q [Dec] #
Generates a Show1
instance declaration for the given data type or data
family instance.
defaultEqualF :: (Eq1 f, Eq a) => f a -> f a -> Bool Source #
Default implementation of equalF
Use as follows:
data F = ...deriveEq1
''F -- Requires TemplateHaskell instanceEqF
F whereequalF
=defaultEqualF
defaultShowsPrecF :: (Show1 f, Show a) => Int -> f a -> ShowS Source #
Default implementation of showsPrecF
Use as follows:
data F = ...deriveShow1
''F -- Requires TemplateHaskell instanceShowF
F whereshowsPrecF
=defaultShowsPrecF
Compositional data types
data ((f :: Type -> Type) :+: (g :: Type -> Type)) a infixl 6 #
Sum of two functors
Instances
f :<: h => f :<: (h :+: g) Source # | Unlike standard Data Types à la Carte, this instance recurses into the left
term. This is due to the left-associativity of |
f :<: f => f :<: (g :+: f) Source # | |
(ShowF (HideInj f), ShowF (HideInj g)) => ShowF (HideInj (f :+: g)) Source # | |
Defined in Data.Comp.Fixplate | |
(Functor f, Functor g) => Functor (f :+: g) | |
(Foldable f, Foldable g) => Foldable (f :+: g) | |
Defined in Data.Generics.Fixplate.Functor fold :: Monoid m => (f :+: g) m -> m # foldMap :: Monoid m => (a -> m) -> (f :+: g) a -> m # foldr :: (a -> b -> b) -> b -> (f :+: g) a -> b # foldr' :: (a -> b -> b) -> b -> (f :+: g) a -> b # foldl :: (b -> a -> b) -> b -> (f :+: g) a -> b # foldl' :: (b -> a -> b) -> b -> (f :+: g) a -> b # foldr1 :: (a -> a -> a) -> (f :+: g) a -> a # foldl1 :: (a -> a -> a) -> (f :+: g) a -> a # toList :: (f :+: g) a -> [a] # length :: (f :+: g) a -> Int # elem :: Eq a => a -> (f :+: g) a -> Bool # maximum :: Ord a => (f :+: g) a -> a # minimum :: Ord a => (f :+: g) a -> a # | |
(Traversable f, Traversable g) => Traversable (f :+: g) | |
Defined in Data.Generics.Fixplate.Functor | |
(EqF f, EqF g) => EqF (f :+: g) | |
(OrdF f, OrdF g) => OrdF (f :+: g) | |
(ShowF f, ShowF g) => ShowF (f :+: g) | |
Defined in Data.Generics.Fixplate.Functor | |
(Eq (f a), Eq (g a)) => Eq ((f :+: g) a) | |
(Ord (f a), Ord (g a)) => Ord ((f :+: g) a) | |
Defined in Data.Generics.Fixplate.Functor | |
(Show (f a), Show (g a)) => Show ((f :+: g) a) | |
Rendering
Instances
Functor f => Functor (HideInj f) Source # | |
Foldable f => Foldable (HideInj f) Source # | |
Defined in Data.Comp.Fixplate fold :: Monoid m => HideInj f m -> m # foldMap :: Monoid m => (a -> m) -> HideInj f a -> m # foldr :: (a -> b -> b) -> b -> HideInj f a -> b # foldr' :: (a -> b -> b) -> b -> HideInj f a -> b # foldl :: (b -> a -> b) -> b -> HideInj f a -> b # foldl' :: (b -> a -> b) -> b -> HideInj f a -> b # foldr1 :: (a -> a -> a) -> HideInj f a -> a # foldl1 :: (a -> a -> a) -> HideInj f a -> a # toList :: HideInj f a -> [a] # length :: HideInj f a -> Int # elem :: Eq a => a -> HideInj f a -> Bool # maximum :: Ord a => HideInj f a -> a # minimum :: Ord a => HideInj f a -> a # | |
Traversable f => Traversable (HideInj f) Source # | |
Defined in Data.Comp.Fixplate | |
ShowF f => ShowF (HideInj f) Source # | |
Defined in Data.Comp.Fixplate | |
(ShowF (HideInj f), ShowF (HideInj g)) => ShowF (HideInj (f :+: g)) Source # | |
Defined in Data.Comp.Fixplate |
showTerm :: (Functor f, Foldable f, ShowF (HideInj f)) => Term f -> String Source #
Represent a Term
as an ASCII drawing
showTermU :: (Functor f, Foldable f, ShowF (HideInj f)) => Term f -> String Source #
Represent a Term
as a Unicode drawing
drawTerm :: (Functor f, Foldable f, ShowF (HideInj f)) => Term f -> IO () Source #
Display a Term
as an ASCII drawing
drawTermU :: (Functor f, Foldable f, ShowF (HideInj f)) => Term f -> IO () Source #
Display a Term
as a Unicode drawing
Making smart constructors
(.:) :: (c -> d) -> (a -> b -> c) -> a -> b -> d infixr 8 #
Compose two functions. f .: g
is similar to f . g
except that g
will be fed two arguments instead of one
before handing its result to f
.
This function is defined as
(f .: g) x y = f (g x y)
Example usage:
concatMap :: (a -> b) -> [a] -> [b] concatMap = concat .: map
Notice how two arguments
(the function and the list)
will be given to map
before the result
is passed to concat
. This is equivalent to:
concatMap f xs = concat (map f xs)