free-functors 1.0.1 → 1.1
raw patch · 13 files changed
+245/−234 lines, 13 filesdep +derive-lifted-instancesdep −algebraic-classesdep ~basedep ~template-haskell
Dependencies added: derive-lifted-instances
Dependencies removed: algebraic-classes
Dependency ranges changed: base, template-haskell
Files
- CHANGELOG +15/−3
- examples/FreeNum.hs +2/−2
- examples/NonEmptyList.hs +2/−2
- examples/Sem.hs +38/−0
- examples/SemSum.hs +1/−10
- free-functors.cabal +4/−4
- src/Data/Functor/Cofree.hs +1/−1
- src/Data/Functor/Free.hs +93/−12
- src/Data/Functor/Free/Internal.hs +25/−99
- src/Data/Functor/HCofree.hs +3/−2
- src/Data/Functor/HFree.hs +25/−34
- src/Data/Functor/HHCofree.hs +7/−7
- src/Data/Functor/HHFree.hs +29/−58
CHANGELOG view
@@ -1,5 +1,17 @@ CHANGELOG +1.0.1 -> 1.1+ - Use derive-lifted-instances i/o algebraic-classes+ - Add deriving instances for `HFree` and `HHFree`+ - Fix `Traversable` and `Foldable` instances of `Free`++1.0 -> 1.0.1+ - Simpler `ShowHelper`++0.8.4 -> 1.0+ - Switch to using the QuantifiedConstraints extension+ - Removed Data.Constraint.Class1+ 0.8.3 -> 0.8.4 - Updated to constraints-0.10 - Updated for GHC 8.4@@ -9,16 +21,16 @@ 0.8.2 -> 0.8.3 - Added Data.Functor.Free.TH to other-modules- + 0.8.1 -> 0.8.2 - Support for `deriveInstances` for classes which have one or more superclasses - `deriveInstances` now also derives the `HasSuperClasses` instance - Expose internal `ShowHelper` datatype- + 0.8 -> 0.8.1 - Added HHCofree - Changes towards support for `SuperClass1` in TH code for `Free`- + 0.7.2 -> 0.8 - Updated for GHC 8.2 - Updated to base-4.10
examples/FreeNum.hs view
@@ -1,4 +1,4 @@-{-# LANGUAGE TemplateHaskell, TypeFamilies, DeriveFunctor, DeriveFoldable, DeriveTraversable, FlexibleInstances #-}+{-# LANGUAGE TypeFamilies, FlexibleInstances, LambdaCase #-} module FreeNum where import Data.Functor.Free@@ -17,7 +17,7 @@ -- Monadic bind is variable substitution subst :: Free Num String -> Free Num a-subst e = e >>= \v -> case v of +subst e = e >>= \case "x" -> 10 _ -> 2
examples/NonEmptyList.hs view
@@ -1,4 +1,4 @@-{-# LANGUAGE TemplateHaskell, TypeFamilies, DeriveFunctor, DeriveFoldable, DeriveTraversable, FlexibleInstances, UndecidableInstances #-}+{-# LANGUAGE TypeFamilies, FlexibleInstances, UndecidableInstances #-} module NonEmptyList where import Data.Functor.Free@@ -25,4 +25,4 @@ -- Test the comonad and foldable instances, returns [15,14,12,9,5]. test :: NonEmptyList Int-test = extend sum $ (pure 1 <> pure 2) <> (pure 3 <> (pure 4 <> pure 5))+test = extend sum $ ((pure 1 <> pure 2) <> pure 3 <> pure 4) <> pure 5
+ examples/Sem.hs view
@@ -0,0 +1,38 @@+{-# LANGUAGE TemplateHaskell, UndecidableInstances, QuantifiedConstraints, FlexibleInstances #-}+module Sem where+ +import Data.Functor.Free++class BaseSem a where+ val :: Int -> a+ add :: a -> a -> a++instance BaseSem Int where+ val = id+ add = (+)++class BaseSem a => AdvSem a where+ mul :: a -> a -> a++instance AdvSem Int where+ mul = (*)++deriveInstances ''BaseSem+deriveInstances ''AdvSem+++test :: Free AdvSem String+test = mul (add (pure "a") (val 3)) (val 5)++evaluate :: Free AdvSem String -> Int+evaluate = rightAdjunct lookupVar+ where+ lookupVar :: String -> Int+ lookupVar "a" = 2+ lookupVar v = error $ "Unknown variable: " ++ v++main :: IO ()+main = putStrLn $ show test ++ " = " ++ show (evaluate test)++vars :: Free AdvSem a -> [a]+vars = foldMap pure
examples/SemSum.hs view
@@ -1,12 +1,10 @@ {-# LANGUAGE - TemplateHaskell, TypeFamilies, DeriveTraversable, FlexibleInstances, UndecidableInstances,+ TemplateHaskell, FlexibleInstances, UndecidableInstances, TypeOperators, MultiParamTypeClasses, ConstraintKinds, UndecidableSuperClasses, QuantifiedConstraints #-} module Sem where -import GHC.Generics-import Data.Algebra import Data.Functor.Free class BaseSem a where@@ -32,13 +30,6 @@ class (a x, b x) => (a + b) x instance (a x, b x) => (a + b) x--type instance Signature (a + b) = Signature a :+: Signature b--instance (AlgebraSignature f, AlgebraSignature g) => AlgebraSignature (f :+: g) where- type Class (f :+: g) = Class f + Class g- evaluate (L1 f) = evaluate f- evaluate (R1 f) = evaluate f deriveInstances ''BaseSem
free-functors.cabal view
@@ -1,5 +1,5 @@ name: free-functors-version: 1.0.1+version: 1.1 synopsis: Free functors, adjoint to functors that forget class constraints. description: A free functor is a left adjoint to a forgetful functor. It used to be the case that the only category that was easy to work with in Haskell was Hask itself, so@@ -44,11 +44,11 @@ Haskell2010 build-depends:- base == 4.12.*,- template-haskell == 2.14.*,+ base >= 4.13 && < 4.15,+ template-haskell >= 2.15 && < 2.17, transformers == 0.5.*, comonad == 5.*,- algebraic-classes == 0.9.*,+ derive-lifted-instances == 0, contravariant == 1.5.*, bifunctors == 5.*, profunctors == 5.*
src/Data/Functor/Cofree.hs view
@@ -34,7 +34,7 @@ counit (Cofree k a) = k a leftAdjunct :: c a => (a -> b) -> a -> Cofree c b-leftAdjunct f a = Cofree f a+leftAdjunct = Cofree -- | @unit = leftAdjunct id@ unit :: c b => b -> Cofree c b
src/Data/Functor/Free.hs view
@@ -1,6 +1,7 @@-{-# OPTIONS_GHC -fno-warn-orphans #-}+{-# OPTIONS_GHC -fno-warn-orphans -fno-warn-unused-matches #-} {-# LANGUAGE- TypeFamilies+ RankNTypes+ , TypeFamilies , TypeOperators , DeriveFunctor , DeriveFoldable@@ -27,6 +28,7 @@ module Data.Functor.Free ( Free(..)+ , deriveFreeInstance , deriveInstances , unit , rightAdjunct@@ -46,18 +48,79 @@ , inR , InitialObject , initial- - -- * Internal- , ShowHelper(..) ) where -import Data.Function-+import Data.Function (fix)+import Data.Monoid (Ap(..)) import Data.Void+import Data.Traversable+import Control.Comonad +import Language.Haskell.TH.Syntax import Data.Functor.Free.Internal+import Data.DeriveLiftedInstances (ShowsPrec(..), deriveInstance, apDeriv, idDeriv) ++-- | The free functor for class @c@.+--+-- @Free c a@ is basically an expression tree with operations from class @c@+-- and variables/placeholders of type @a@, created with `unit`.+-- Monadic bind allows you to replace each of these variables with another sub-expression.+newtype Free c a = Free { runFree :: forall b. c b => (a -> b) -> b }++-- | `unit` allows you to create @`Free` c@ values, together with the operations from the class @c@.+unit :: a -> Free c a+unit a = Free $ \k -> k a++-- | `rightAdjunct` is the destructor of @`Free` c@ values.+rightAdjunct :: c b => (a -> b) -> Free c a -> b+rightAdjunct f g = runFree g f++-- | @counit = rightAdjunct id@+counit :: c a => Free c a -> a+counit = rightAdjunct id++-- | @leftAdjunct f = f . unit@+leftAdjunct :: (Free c a -> b) -> a -> b+leftAdjunct f = f . unit++-- | @transform f as = as >>= f unit@+--+-- @transform f . transform g = transform (g . f)@+transform :: (forall r. c r => (b -> r) -> a -> r) -> Free c a -> Free c b+transform t (Free f) = Free (f . t)+++instance Functor (Free c) where+ fmap f = transform (. f)++instance Applicative (Free c) where+ pure = unit+ fs <*> as = transform (\k f -> rightAdjunct (k . f) as) fs++instance Monad (Free c) where+ return = unit+ as >>= f = transform (\k -> rightAdjunct k . f) as++instance (forall f x. Applicative f => c (Ap f (Free c x))) => Foldable (Free c) where+ foldMap = foldMapDefault++instance (forall f x. Applicative f => c (Ap f (Free c x))) => Traversable (Free c) where+ traverse f = getAp . rightAdjunct (Ap . fmap unit . f)++instance (Show a, c ShowsPrec) => Show (Free c a) where+ showsPrec p = showsPrec p . rightAdjunct (\a -> ShowsPrec $ \d -> showParen (d > 10) $ showString "pure " . showsPrec 11 a)+++newtype Extract a = Extract { getExtract :: a }+newtype Duplicate f a = Duplicate { getDuplicate :: f (f a) }+instance (forall x. c (Extract x), forall x. c (Duplicate (Free c) x))+ => Comonad (Free c) where+ extract = getExtract . rightAdjunct Extract+ duplicate = getDuplicate . rightAdjunct (Duplicate . unit . unit)++ -- | @unfold f = coproduct (unfold f) unit . f@ -- -- `inL` and `inR` are useful here. For example, the following creates the list @[1..10]@ as a @Free Monoid@:@@ -94,9 +157,27 @@ initial :: c r => InitialObject c -> r initial = rightAdjunct absurd +-- | Derive the instance of @`Free` c a@ for the class @c@.+--+-- For example:+--+-- @deriveFreeInstance ''Num@+deriveFreeInstance :: Name -> Q [Dec]+deriveFreeInstance = deriveFreeInstance' ''Free 'Free 'runFree -deriveInstances ''Num-deriveInstances ''Fractional-deriveInstances ''Floating-deriveInstances ''Semigroup-deriveInstances ''Monoid+--- | Derive the instances of @`Free` c a@ for the class @c@, `Show`, `Foldable` and `Traversable`.+--+-- For example:+--+-- @deriveInstances ''Num@+deriveInstances :: Name -> Q [Dec]+deriveInstances = deriveInstances' ''Free 'Free 'runFree++deriveFreeInstance' ''Free 'Free 'runFree ''Num+deriveFreeInstance' ''Free 'Free 'runFree ''Fractional+deriveFreeInstance' ''Free 'Free 'runFree ''Floating+deriveFreeInstance' ''Free 'Free 'runFree ''Semigroup+deriveFreeInstance' ''Free 'Free 'runFree ''Monoid++deriveInstance (apDeriv idDeriv) [t|forall f a c. (Applicative f, Fractional a) => Fractional (Ap f a)|]+deriveInstance (apDeriv idDeriv) [t|forall f a c. (Applicative f, Floating a) => Floating (Ap f a)|]
src/Data/Functor/Free/Internal.hs view
@@ -1,6 +1,7 @@ {-# LANGUAGE GADTs , RankNTypes+ , ViewPatterns , TypeOperators , DeriveFunctor , DeriveFoldable@@ -16,112 +17,37 @@ #-} module Data.Functor.Free.Internal where -import Control.Comonad-import Data.Algebra-import Data.Algebra.TH-import Language.Haskell.TH.Syntax-import Data.Traversable---- | The free functor for class @c@.------ @Free c a@ is basically an expression tree with operations from class @c@--- and variables/placeholders of type @a@, created with `unit`.--- Monadic bind allows you to replace each of these variables with another sub-expression.-newtype Free c a = Free { runFree :: forall b. c b => (a -> b) -> b }---- | `unit` allows you to create @`Free` c@ values, together with the operations from the class @c@.-unit :: a -> Free c a-unit a = Free $ \k -> k a---- | `rightAdjunct` is the destructor of @`Free` c@ values.-rightAdjunct :: c b => (a -> b) -> Free c a -> b-rightAdjunct f g = runFree g f---- | @counit = rightAdjunct id@-counit :: c a => Free c a -> a-counit = rightAdjunct id---- | @leftAdjunct f = f . unit@-leftAdjunct :: (Free c a -> b) -> a -> b-leftAdjunct f = f . unit---- | @transform f as = as >>= f unit@------ @transform f . transform g = transform (g . f)@-transform :: (forall r. c r => (b -> r) -> a -> r) -> Free c a -> Free c b-transform t (Free f) = Free (f . t)---instance Functor (Free c) where- fmap f = transform (. f)--instance Applicative (Free c) where- pure = unit- fs <*> as = transform (\k f -> rightAdjunct (k . f) as) fs--instance Monad (Free c) where- return = unit- as >>= f = transform (\k -> rightAdjunct k . f) as--newtype Extract a = Extract { getExtract :: a }-newtype Duplicate f a = Duplicate { getDuplicate :: f (f a) }-instance (forall x. c (Extract x), forall x. c (Duplicate (Free c) x))- => Comonad (Free c) where- extract = getExtract . rightAdjunct Extract- duplicate = getDuplicate . rightAdjunct (Duplicate . unit . unit)- --class (Class f x) => Class' f x where evaluate' :: AlgebraSignature f => f x -> x-instance (Class f x) => Class' f x where evaluate' = evaluate--newtype LiftAFree c f a = LiftAFree { getLiftAFree :: f (Free c a) }--instance (forall x. c x => Class' f x) => Algebra f (Free c a) where- algebra fa = Free $ \k -> evaluate' (fmap (rightAdjunct k) fa)- -instance (Applicative f, forall x. c x => Class' s x) => Algebra s (LiftAFree c f a) where- algebra = LiftAFree . fmap algebra . traverse getLiftAFree--instance (forall f x. Applicative f => c (LiftAFree c f x)) => Foldable (Free c) where- foldMap = foldMapDefault+import Data.Monoid (Ap(..)) -instance (forall f x. Applicative f => c (LiftAFree c f x)) => Traversable (Free c) where- traverse f = getLiftAFree . rightAdjunct (LiftAFree . fmap unit . f)+import Language.Haskell.TH.Syntax+import Data.DeriveLiftedInstances -data ShowHelper a where - ShowUnit :: a -> ShowHelper a- ShowRec :: Show (f (ShowHelper a)) => f (ShowHelper a) -> ShowHelper a+kExp :: Q Exp+kExp = pure . VarE $ mkName "k" -instance Show (f (ShowHelper a)) => Algebra f (ShowHelper a) where- algebra = ShowRec+kPat :: Q Pat+kPat = pure . VarP $ mkName "k" -instance Show a => Show (ShowHelper a) where- showsPrec p (ShowUnit a) = showParen (p > 10) $ showString "unit " . showsPrec 11 a- showsPrec p (ShowRec f) = showsPrec p f+freeDeriv :: Name -> Name -> Derivator+freeDeriv (pure . ConE -> free) (pure . VarE -> runFree) = idDeriv {+ res = \e -> [| $free (\ $kPat -> $e) |],+ var = \fold v -> [| $(fold (\w -> [| fmap $w |]) [| \f -> $runFree f $kExp |]) $v |]+} -instance (Show a, Show (Signature c (ShowHelper a)), c (ShowHelper a)) => Show (Free c a) where- showsPrec p = showsPrec p . rightAdjunct ShowUnit+deriveFreeInstance' :: Name -> Name -> Name -> Name -> Q [Dec]+deriveFreeInstance' (pure . ConT -> free) cfree runFree (pure . ConT -> clss)+ = deriveInstance+ (freeDeriv cfree runFree)+ [t| forall a c. (forall x. c x :=> $clss x) => $clss ($free c a) |] +deriveInstances' :: Name -> Name -> Name -> Name -> Q [Dec]+deriveInstances' tfree cfree runFree nm@(pure . ConT -> clss) =+ concat <$> sequenceA+ [ deriveFreeInstance' tfree cfree runFree nm+ , deriveInstance showDeriv [t| $clss ShowsPrec |]+ , deriveInstance (apDeriv idDeriv) [t| forall f a c. (Applicative f, $clss a) => $clss (Ap f a) |]+ ] class (a => b) => a :=> b instance (a => b) => a :=> b---- | Derive the instances of @`Free` c a@ for the class @c@, `Show`, `Foldable` and `Traversable`.------ For example:------ @deriveInstances ''Num@-deriveInstances :: Name -> Q [Dec]-deriveInstances nm = - concat <$> sequenceA- [ deriveSignature nm- , deriveInstanceWith_skipSignature freeHeader $ return []- , deriveInstanceWith_skipSignature liftAFreeHeader $ return []- , deriveInstanceWith_skipSignature showHelperHeader $ return []- ]- where- freeHeader = [t|forall a c. (forall x. c x :=> $clss x) => $clss (Free c a)|]- liftAFreeHeader = [t|forall f a c. (Applicative f, forall x. c x :=> $clss x) => $clss (LiftAFree c f a)|]- showHelperHeader = [t|forall a. Show a => $clss (ShowHelper a)|]- clss = pure $ ConT nm
src/Data/Functor/HCofree.hs view
@@ -41,7 +41,7 @@ counit (HCofree k fa) = k fa leftAdjunct :: c f => (f :~> g) -> f :~> HCofree c g-leftAdjunct k fa = HCofree k fa+leftAdjunct = HCofree -- | @unit = leftAdjunct id@ unit :: c g => g :~> HCofree c g@@ -55,7 +55,7 @@ transform t (HCofree k a) = HCofree (t k) a hfmap :: (f :~> g) -> HCofree c f :~> HCofree c g-hfmap f = transform (\k -> f . k)+hfmap f = transform (f .) hextend :: (HCofree c f :~> g) -> HCofree c f :~> HCofree c g hextend f = transform (\k -> f . leftAdjunct k)@@ -81,6 +81,7 @@ instance (forall x. c x => Foldable x) => Foldable (HCofree c g) where foldMap f (HCofree _ a) = foldMap f a+ foldMap' f (HCofree _ a) = foldMap' f a fold (HCofree _ a) = fold a foldr f z (HCofree _ a) = foldr f z a foldl f z (HCofree _ a) = foldl f z a
src/Data/Functor/HFree.hs view
@@ -1,7 +1,9 @@+{-# OPTIONS_GHC -fno-warn-unused-matches #-} {-# LANGUAGE RankNTypes , TypeOperators , ConstraintKinds+ , TemplateHaskell , UndecidableInstances , QuantifiedConstraints #-}@@ -24,17 +26,31 @@ module Data.Functor.HFree where import Control.Applicative+import Control.Monad (join) import Control.Monad.Trans.Class import Data.Functor.Identity import Data.Functor.Contravariant import Data.Functor.Contravariant.Divisible +import Language.Haskell.TH.Syntax (Q, Name, Dec)+import Data.Functor.Free.Internal+ -- | Natural transformations. type f :~> g = forall b. f b -> g b -- | The higher order free functor for constraint @c@. newtype HFree c f a = HFree { runHFree :: forall g. c g => (f :~> g) -> g a } ++-- | Derive the instance of @`HFree` c f a@ for the class @c@,.+--+-- For example:+--+-- @deriveHFreeInstance ''Functor@+deriveHFreeInstance :: Name -> Q [Dec]+deriveHFreeInstance = deriveFreeInstance' ''HFree 'HFree 'runHFree++ unit :: f :~> HFree c f unit fa = HFree $ \k -> k fa @@ -54,7 +70,7 @@ -- transform t = HFree . (. t) . runHFree hfmap :: (f :~> g) -> HFree c f :~> HFree c g-hfmap f = transform (\k -> k . f)+hfmap f = transform (. f) bind :: (f :~> HFree c g) -> HFree c f :~> HFree c g bind f = transform (\k -> rightAdjunct k . f)@@ -72,44 +88,19 @@ iter f = runIdentity . rightAdjunct (Identity . f) wrap :: f (HFree Monad f a) -> HFree Monad f a-wrap as = unit as >>= id+wrap as = join (unit as) -instance (forall x. c x => Functor x) => Functor (HFree c f) where- fmap f (HFree g) = HFree $ \k -> fmap f (g k)- a <$ HFree g = HFree $ \k -> a <$ g k--instance (forall x. c x => Applicative x) => Applicative (HFree c f) where- pure a = HFree $ const (pure a)- HFree f <*> HFree g = HFree $ \k -> f k <*> g k- HFree f <* HFree g = HFree $ \k -> f k <* g k- HFree f *> HFree g = HFree $ \k -> f k *> g k- liftA2 f (HFree g) (HFree h) = HFree $ \k -> liftA2 f (g k) (h k)--instance (forall x. c x => Alternative x) => Alternative (HFree c f) where- empty = HFree $ const empty- HFree f <|> HFree g = HFree $ \k -> f k <|> g k- many (HFree f) = HFree $ \k -> many (f k)- some (HFree f) = HFree $ \k -> some (f k)+deriveFreeInstance' ''HFree 'HFree 'runHFree ''Functor+deriveFreeInstance' ''HFree 'HFree 'runHFree ''Applicative+deriveFreeInstance' ''HFree 'HFree 'runHFree ''Alternative -- | The free monad of a functor.-instance (forall x. c x => Monad x) => Monad (HFree c f) where- return = pure- HFree f >>= g = HFree $ \k -> f k >>= rightAdjunct k . g- HFree f >> HFree g = HFree $ \k -> f k >> g k- fail s = HFree $ const (fail s)+deriveFreeInstance' ''HFree 'HFree 'runHFree ''Monad -- HFree Monad is only a monad transformer if rightAdjunct is called with monad morphisms. -- F.e. lift . return == return fails if the results are inspected with rightAdjunct (const Nothing). -instance (forall x. c x => Contravariant x) => Contravariant (HFree c f) where- contramap f (HFree g) = HFree $ \k -> contramap f (g k)- a >$ HFree g = HFree $ \k -> a >$ g k--instance (forall x. c x => Divisible x) => Divisible (HFree c f) where- divide f (HFree a) (HFree b) = HFree $ \k -> divide f (a k) (b k)- conquer = HFree $ const conquer--instance (forall x. c x => Decidable x) => Decidable (HFree c f) where- choose f (HFree a) (HFree b) = HFree $ \k -> choose f (a k) (b k)- lose f = HFree $ const (lose f)+deriveFreeInstance' ''HFree 'HFree 'runHFree ''Contravariant+deriveFreeInstance' ''HFree 'HFree 'runHFree ''Divisible+deriveFreeInstance' ''HFree 'HFree 'runHFree ''Decidable
src/Data/Functor/HHCofree.hs view
@@ -48,7 +48,7 @@ counit (HHCofree k fa) = k fa leftAdjunct :: c f => (f :~~> g) -> f :~~> HHCofree c g-leftAdjunct k fa = HHCofree k fa+leftAdjunct = HHCofree -- | @unit = leftAdjunct id@ unit :: c g => g :~~> HHCofree c g@@ -62,7 +62,7 @@ transform t (HHCofree k a) = HHCofree (t k) a hfmap :: (f :~~> g) -> HHCofree c f :~~> HHCofree c g-hfmap f = transform (\k -> f . k)+hfmap f = transform (f .) hextend :: (HHCofree c f :~~> g) -> HHCofree c f :~~> HHCofree c g hextend f = transform (\k -> f . leftAdjunct k)@@ -74,7 +74,7 @@ instance BifunctorComonad (HHCofree c) where biextract = counit biextend = hextend- + instance ProfunctorFunctor (HHCofree c) where promap = hfmap @@ -87,21 +87,21 @@ bimap f g (HHCofree k a) = HHCofree k (bimap f g a) first f (HHCofree k a) = HHCofree k (first f a) second f (HHCofree k a) = HHCofree k (second f a)- + instance (forall x. c x => Profunctor x) => Profunctor (HHCofree c g) where dimap f g (HHCofree k a) = HHCofree k (dimap f g a) lmap f (HHCofree k a) = HHCofree k (lmap f a) rmap f (HHCofree k a) = HHCofree k (rmap f a) f #. HHCofree k g = HHCofree k (f #. g) HHCofree k g .# f = HHCofree k (g .# f)- + instance (forall x. c x => Strong x) => Strong (HHCofree c f) where first' (HHCofree k a) = HHCofree k (first' a) second' (HHCofree k a) = HHCofree k (second' a)- + instance (forall x. c x => Choice x) => Choice (HHCofree c f) where left' (HHCofree k a) = HHCofree k (left' a) right' (HHCofree k a) = HHCofree k (right' a)- + instance (forall x. c x => Closed x) => Closed (HHCofree c f) where closed (HHCofree k a) = HHCofree k (closed a)
src/Data/Functor/HHFree.hs view
@@ -1,7 +1,9 @@+{-# OPTIONS_GHC -fno-warn-unused-matches #-} {-# LANGUAGE RankNTypes , TypeOperators , ConstraintKinds+ , TemplateHaskell , UndecidableInstances , QuantifiedConstraints #-}@@ -26,20 +28,31 @@ import Control.Arrow import Control.Category import Data.Bifunctor (Bifunctor)-import qualified Data.Bifunctor as B (Bifunctor(..)) import Data.Bifunctor.Functor-import Data.Biapplicative (Biapplicative(..))+import Data.Biapplicative (Biapplicative) import Data.Profunctor-import Data.Profunctor.Unsafe import Data.Profunctor.Monad +import Language.Haskell.TH.Syntax (Q, Name, Dec)+import Data.Functor.Free.Internal + -- | Natural transformations. type f :~~> g = forall a b. f a b -> g a b -- | The higher order free functor over two type parameters for constraint @c@. newtype HHFree c f a b = HHFree { runHHFree :: forall g. c g => (f :~~> g) -> g a b } ++-- | Derive the instance of @`HHFree` c f a b@ for the class @c@,.+--+-- For example:+--+-- @deriveHHFreeInstance ''Category@+deriveHHFreeInstance :: Name -> Q [Dec]+deriveHHFreeInstance = deriveFreeInstance' ''HHFree 'HHFree 'runHHFree++ unit :: f :~~> HHFree c f unit fa = HHFree $ \k -> k fa @@ -59,7 +72,7 @@ -- transform t = HHFree . (. t) . runHHFree hfmap :: (f :~~> g) -> HHFree c f :~~> HHFree c g-hfmap f = transform (\k -> k . f)+hfmap f = transform (. f) bind :: (f :~~> HHFree c g) -> HHFree c f :~~> HHFree c g bind f = transform (\k -> rightAdjunct k . f)@@ -79,61 +92,19 @@ projoin = bind id -instance (forall x. c x => Category x) => Category (HHFree c f) where- id = HHFree $ const id- HHFree f . HHFree g = HHFree $ \k -> f k . g k--instance (forall x. c x => Arrow x) => Arrow (HHFree c f) where- arr f = HHFree $ const (arr f)- first (HHFree f) = HHFree $ \k -> first (f k)- second (HHFree f) = HHFree $ \k -> second (f k)- HHFree f *** HHFree g = HHFree $ \k -> f k *** g k- HHFree f &&& HHFree g = HHFree $ \k -> f k &&& g k--instance (forall x. c x => ArrowZero x) => ArrowZero (HHFree c f) where- zeroArrow = HHFree $ const zeroArrow--instance (forall x. c x => ArrowPlus x) => ArrowPlus (HHFree c f) where- HHFree f <+> HHFree g = HHFree $ \k -> f k <+> g k--instance (forall x. c x => ArrowChoice x) => ArrowChoice (HHFree c f) where- left (HHFree f) = HHFree $ \k -> left (f k)- right (HHFree f) = HHFree $ \k -> right (f k)- HHFree f +++ HHFree g = HHFree $ \k -> f k +++ g k- HHFree f ||| HHFree g = HHFree $ \k -> f k ||| g k+deriveFreeInstance' ''HHFree 'HHFree 'runHHFree ''Category+deriveFreeInstance' ''HHFree 'HHFree 'runHHFree ''Arrow+deriveFreeInstance' ''HHFree 'HHFree 'runHHFree ''ArrowZero+deriveFreeInstance' ''HHFree 'HHFree 'runHHFree ''ArrowPlus+deriveFreeInstance' ''HHFree 'HHFree 'runHHFree ''ArrowChoice+deriveFreeInstance' ''HHFree 'HHFree 'runHHFree ''ArrowLoop instance (forall x. c x => ArrowApply x) => ArrowApply (HHFree c f) where app = HHFree $ \k -> app . arr (first (rightAdjunct k)) -instance (forall x. c x => ArrowLoop x) => ArrowLoop (HHFree c f) where- loop (HHFree f) = HHFree $ \k -> loop (f k)--instance (forall x. c x => Bifunctor x) => Bifunctor (HHFree c f) where- first f (HHFree g) = HHFree $ \k -> B.first f (g k)- second f (HHFree g) = HHFree $ \k -> B.second f (g k)- bimap p q (HHFree g) = HHFree $ \k -> B.bimap p q (g k)--instance (forall x. c x => Biapplicative x) => Biapplicative (HHFree c f) where- bipure a b = HHFree $ const (bipure a b)- HHFree f <<*>> HHFree g = HHFree $ \k -> f k <<*>> g k- HHFree f *>> HHFree g = HHFree $ \k -> f k *>> g k- HHFree f <<* HHFree g = HHFree $ \k -> f k <<* g k- biliftA2 p q (HHFree g) (HHFree h) = HHFree $ \k -> biliftA2 p q (g k) (h k)--instance (forall x. c x => Profunctor x) => Profunctor (HHFree c f) where- lmap f (HHFree g) = HHFree $ \k -> lmap f (g k)- rmap f (HHFree g) = HHFree $ \k -> rmap f (g k)- f #. HHFree g = HHFree $ \k -> f #. g k- HHFree g .# f = HHFree $ \k -> g k .# f- dimap p q (HHFree g) = HHFree $ \k -> dimap p q (g k)--instance (forall x. c x => Strong x) => Strong (HHFree c f) where- first' (HHFree f) = HHFree $ \k -> first' (f k)- second' (HHFree f) = HHFree $ \k -> second' (f k)--instance (forall x. c x => Choice x) => Choice (HHFree c f) where- left' (HHFree f) = HHFree $ \k -> left' (f k)- right' (HHFree f) = HHFree $ \k -> right' (f k)--instance (forall x. c x => Closed x) => Closed (HHFree c f) where- closed (HHFree f) = HHFree $ \k -> closed (f k)+deriveFreeInstance' ''HHFree 'HHFree 'runHHFree ''Bifunctor+deriveFreeInstance' ''HHFree 'HHFree 'runHHFree ''Biapplicative+deriveFreeInstance' ''HHFree 'HHFree 'runHHFree ''Profunctor+deriveFreeInstance' ''HHFree 'HHFree 'runHHFree ''Strong+deriveFreeInstance' ''HHFree 'HHFree 'runHHFree ''Choice+deriveFreeInstance' ''HHFree 'HHFree 'runHHFree ''Closed