compdata 0.6.1.4 → 0.13.1
raw patch · 155 files changed
Files
- CHANGELOG.md +10/−0
- benchmark/Benchmark.hs +7/−6
- benchmark/DataTypes.hs +8/−8
- benchmark/DataTypes/Comp.hs +12/−5
- benchmark/DataTypes/Standard.hs +10/−11
- benchmark/Functions/Comp/Desugar.hs +6/−4
- benchmark/Functions/Comp/Eval.hs +34/−28
- benchmark/Functions/Comp/FreeVars.hs +2/−1
- benchmark/Functions/Comp/HOAS.hs +54/−0
- benchmark/Functions/Comp/Inference.hs +12/−5
- benchmark/Functions/Standard/Eval.hs +11/−4
- benchmark/Functions/Standard/FreeVars.hs +1/−1
- benchmark/Functions/Standard/Inference.hs +6/−3
- compdata.cabal +255/−202
- examples/Examples/Automata/Compiler.hs +0/−192
- examples/Examples/Common.hs +5/−1
- examples/Examples/Desugar.hs +4/−2
- examples/Examples/Eval.hs +3/−3
- examples/Examples/EvalM.hs +3/−3
- examples/Examples/Multi/Desugar.hs +1/−1
- examples/Examples/Multi/Eval.hs +3/−3
- examples/Examples/Multi/EvalM.hs +3/−3
- examples/Examples/MultiParam/FOL.hs +0/−436
- examples/Examples/MultiParam/Lambda.hs +0/−106
- examples/Examples/Param/Graph.hs +0/−77
- examples/Examples/Param/Lambda.hs +0/−131
- examples/Examples/Param/Names.hs +0/−113
- examples/Examples/Thunk.hs +84/−0
- src/Data/Comp.hs +3/−3
- src/Data/Comp/Algebra.hs +32/−36
- src/Data/Comp/Annotation.hs +21/−43
- src/Data/Comp/Arbitrary.hs +11/−9
- src/Data/Comp/Automata.hs +0/−483
- src/Data/Comp/Automata/Product.hs +0/−25
- src/Data/Comp/Automata/Product/Derive.hs +0/−73
- src/Data/Comp/Decompose.hs +14/−13
- src/Data/Comp/DeepSeq.hs +12/−10
- src/Data/Comp/Derive.hs +9/−22
- src/Data/Comp/Derive/Arbitrary.hs +12/−17
- src/Data/Comp/Derive/DeepSeq.hs +10/−18
- src/Data/Comp/Derive/Equality.hs +7/−8
- src/Data/Comp/Derive/Foldable.hs +21/−22
- src/Data/Comp/Derive/HaskellStrict.hs +30/−21
- src/Data/Comp/Derive/Injections.hs +0/−82
- src/Data/Comp/Derive/Ordering.hs +9/−9
- src/Data/Comp/Derive/Projections.hs +0/−95
- src/Data/Comp/Derive/Show.hs +50/−12
- src/Data/Comp/Derive/SmartAConstructors.hs +8/−8
- src/Data/Comp/Derive/SmartConstructors.hs +6/−6
- src/Data/Comp/Derive/Traversable.hs +15/−16
- src/Data/Comp/Derive/Utils.hs +88/−39
- src/Data/Comp/Desugar.hs +8/−4
- src/Data/Comp/Equality.hs +7/−6
- src/Data/Comp/Generic.hs +25/−7
- src/Data/Comp/Mapping.hs +102/−0
- src/Data/Comp/Matching.hs +8/−6
- src/Data/Comp/Multi.hs +78/−78
- src/Data/Comp/Multi/Algebra.hs +18/−12
- src/Data/Comp/Multi/Annotation.hs +17/−12
- src/Data/Comp/Multi/Derive.hs +4/−4
- src/Data/Comp/Multi/Derive/Equality.hs +10/−10
- src/Data/Comp/Multi/Derive/HFoldable.hs +14/−15
- src/Data/Comp/Multi/Derive/HFunctor.hs +8/−7
- src/Data/Comp/Multi/Derive/HTraversable.hs +9/−13
- src/Data/Comp/Multi/Derive/Injections.hs +0/−87
- src/Data/Comp/Multi/Derive/Ordering.hs +21/−20
- src/Data/Comp/Multi/Derive/Projections.hs +0/−100
- src/Data/Comp/Multi/Derive/Show.hs +9/−8
- src/Data/Comp/Multi/Derive/SmartAConstructors.hs +9/−9
- src/Data/Comp/Multi/Derive/SmartConstructors.hs +8/−8
- src/Data/Comp/Multi/Desugar.hs +7/−4
- src/Data/Comp/Multi/Equality.hs +6/−5
- src/Data/Comp/Multi/Generic.hs +15/−9
- src/Data/Comp/Multi/HFoldable.hs +12/−6
- src/Data/Comp/Multi/HFunctor.hs +22/−8
- src/Data/Comp/Multi/HTraversable.hs +13/−4
- src/Data/Comp/Multi/Mapping.hs +95/−0
- src/Data/Comp/Multi/Number.hs +0/−50
- src/Data/Comp/Multi/Ops.hs +95/−40
- src/Data/Comp/Multi/Ordering.hs +8/−6
- src/Data/Comp/Multi/Projection.hs +77/−0
- src/Data/Comp/Multi/Show.hs +9/−6
- src/Data/Comp/Multi/Sum.hs +13/−96
- src/Data/Comp/Multi/Term.hs +13/−9
- src/Data/Comp/Multi/Variables.hs +50/−38
- src/Data/Comp/MultiParam.hs +0/−34
- src/Data/Comp/MultiParam/Algebra.hs +0/−349
- src/Data/Comp/MultiParam/Annotation.hs +0/−80
- src/Data/Comp/MultiParam/Derive.hs +0/−55
- src/Data/Comp/MultiParam/Derive/Equality.hs +0/−78
- src/Data/Comp/MultiParam/Derive/HDifunctor.hs +0/−85
- src/Data/Comp/MultiParam/Derive/Injections.hs +0/−91
- src/Data/Comp/MultiParam/Derive/Ordering.hs +0/−93
- src/Data/Comp/MultiParam/Derive/Projections.hs +0/−108
- src/Data/Comp/MultiParam/Derive/Show.hs +0/−87
- src/Data/Comp/MultiParam/Derive/SmartAConstructors.hs +0/−48
- src/Data/Comp/MultiParam/Derive/SmartConstructors.hs +0/−72
- src/Data/Comp/MultiParam/Desugar.hs +0/−44
- src/Data/Comp/MultiParam/Equality.hs +0/−64
- src/Data/Comp/MultiParam/FreshM.hs +0/−54
- src/Data/Comp/MultiParam/HDifunctor.hs +0/−40
- src/Data/Comp/MultiParam/HDitraversable.hs +0/−29
- src/Data/Comp/MultiParam/Ops.hs +0/−126
- src/Data/Comp/MultiParam/Ordering.hs +0/−67
- src/Data/Comp/MultiParam/Show.hs +0/−42
- src/Data/Comp/MultiParam/Sum.hs +0/−180
- src/Data/Comp/MultiParam/Term.hs +0/−123
- src/Data/Comp/Number.hs +0/−45
- src/Data/Comp/Ops.hs +99/−24
- src/Data/Comp/Ordering.hs +7/−6
- src/Data/Comp/Param.hs +0/−32
- src/Data/Comp/Param/Algebra.hs +0/−964
- src/Data/Comp/Param/Annotation.hs +0/−79
- src/Data/Comp/Param/Derive.hs +0/−57
- src/Data/Comp/Param/Derive/Difunctor.hs +0/−96
- src/Data/Comp/Param/Derive/Ditraversable.hs +0/−88
- src/Data/Comp/Param/Derive/Equality.hs +0/−84
- src/Data/Comp/Param/Derive/Injections.hs +0/−86
- src/Data/Comp/Param/Derive/Ordering.hs +0/−93
- src/Data/Comp/Param/Derive/Projections.hs +0/−101
- src/Data/Comp/Param/Derive/Show.hs +0/−92
- src/Data/Comp/Param/Derive/SmartAConstructors.hs +0/−47
- src/Data/Comp/Param/Derive/SmartConstructors.hs +0/−62
- src/Data/Comp/Param/Desugar.hs +0/−45
- src/Data/Comp/Param/Difunctor.hs +0/−36
- src/Data/Comp/Param/Ditraversable.hs +0/−28
- src/Data/Comp/Param/Equality.hs +0/−67
- src/Data/Comp/Param/FreshM.hs +0/−49
- src/Data/Comp/Param/Ops.hs +0/−127
- src/Data/Comp/Param/Ordering.hs +0/−77
- src/Data/Comp/Param/Show.hs +0/−41
- src/Data/Comp/Param/Sum.hs +0/−186
- src/Data/Comp/Param/Term.hs +0/−109
- src/Data/Comp/Param/Thunk.hs +0/−127
- src/Data/Comp/Projection.hs +76/−0
- src/Data/Comp/Render.hs +36/−0
- src/Data/Comp/Show.hs +12/−4
- src/Data/Comp/SubsumeCommon.hs +168/−0
- src/Data/Comp/Sum.hs +51/−107
- src/Data/Comp/Term.hs +21/−6
- src/Data/Comp/TermRewriting.hs +10/−9
- src/Data/Comp/Thunk.hs +26/−21
- src/Data/Comp/Unification.hs +8/−12
- src/Data/Comp/Variables.hs +44/−29
- testsuite/tests/Data/Comp/Equality_Test.hs +4/−5
- testsuite/tests/Data/Comp/Examples/Comp.hs +0/−4
- testsuite/tests/Data/Comp/Examples/Multi.hs +0/−1
- testsuite/tests/Data/Comp/Examples/MultiParam.hs +0/−34
- testsuite/tests/Data/Comp/Examples/Param.hs +0/−38
- testsuite/tests/Data/Comp/Examples_Test.hs +1/−8
- testsuite/tests/Data/Comp/Multi/Variables_Test.hs +5/−5
- testsuite/tests/Data/Comp/Subsume_Test.hs +56/−0
- testsuite/tests/Data/Comp/Variables_Test.hs +12/−9
- testsuite/tests/Data/Comp_Test.hs +3/−1
- testsuite/tests/Test/Utils.hs +5/−4
+ CHANGELOG.md view
@@ -0,0 +1,10 @@+0.13.1+---++- Compatibility with GHC 9.8++0.13+---++- Compatibility with GHC 9.2, 9.4, 9.6+- GHC version 9.0 and older no longer supported
benchmark/Benchmark.hs view
@@ -11,8 +11,9 @@ import Control.DeepSeq import Test.QuickCheck.Arbitrary import Test.QuickCheck.Gen-import System.Random+import Test.QuickCheck.Random + aExpr :: SugarExpr aExpr = iIf ((iVInt 1 `iGt` (iVInt 2 `iMinus` iVInt 1)) `iOr` ((iVInt 1 `iGt` (iVInt 2 `iMinus` iVInt 1))))@@ -41,10 +42,10 @@ where depth = 15 standardBenchmarks :: (PExpr, SugarExpr, String) -> Benchmark-standardBenchmarks (sExpr,aExpr,n) = rnf aExpr `seq` rnf sExpr `seq` getBench (sExpr, aExpr,n)- where getBench (sExpr, aExpr,n) = bgroup n paperBenchmarks+standardBenchmarks (sExpr,aExpr,n) = rnf aExpr `seq` rnf sExpr `seq` getBench n+ where getBench n = bgroup n paperBenchmarks -- these are the benchmarks for evaluation- evalBenchmarks = [+ _evalBenchmarks = [ bench "evalDesug" (nf A.desugEval2 aExpr), bench "evalDesug (fusion)" (nf A.desugEval2' aExpr), bench "evalDesug (comparison)" (nf S.desugEval2 sExpr),@@ -96,7 +97,7 @@ bench "freeVarsU" (nf S.freeVarsGen sExpr), bench "freeVars (comparison)" (nf S.freeVars sExpr)] -- these are all the benchmarks- allBenchmarks = [+ _allBenchmarks = [ bench "Comp.desug" (nf A.desugExpr aExpr), bench "Comp.desug'" (nf A.desugExpr' aExpr), bench "Comp.desugAlg" (nf A.desugExpr2 aExpr),@@ -138,7 +139,7 @@ randStdBenchmarks :: Int -> IO Benchmark randStdBenchmarks s = do- rand <- getStdGen+ rand <- newQCGen let ty = unGen arbitrary rand s putStr "size of the type term: " print $ size ty
benchmark/DataTypes.hs view
@@ -1,14 +1,14 @@-{-# LANGUAGE TypeSynonymInstances, CPP #-}+{-# LANGUAGE TypeSynonymInstances, FlexibleInstances, CPP #-} module DataTypes where +-- Control.Monad.Fail import is redundant since GHC 8.8.1+#if !MIN_VERSION_base(4,13,0)+import Control.Monad.Fail+#endif++ type Err = Either String -#if __GLASGOW_HASKELL__ < 700-instance Monad Err where- return = Right- e >>= f = case e of - Left m -> Left m- Right x -> f x+instance MonadFail Err where fail = Left-#endif
benchmark/DataTypes/Comp.hs view
@@ -7,7 +7,9 @@ TypeOperators, ScopedTypeVariables, TypeSynonymInstances,- DeriveFunctor#-}+ DeriveFunctor,+ ConstraintKinds,+ DeriveGeneric, DeriveAnyClass #-} module DataTypes.Comp ( module DataTypes.Comp,@@ -19,15 +21,16 @@ import Data.Comp import Data.Comp.Ops import Data.Comp.Arbitrary ()-import Data.Comp.Show+import Data.Comp.Show () import Data.Traversable-import Test.QuickCheck.Arbitrary import Test.QuickCheck.Gen import Test.QuickCheck.Property import Control.Monad hiding (sequence_,mapM) import Prelude hiding (sequence_,mapM) +import GHC.Generics (Generic)+ -- base values type ValueSig = Value@@ -39,6 +42,8 @@ type BaseTypeSig = ValueT type BaseType = Term BaseTypeSig ++ data ValueT e = TInt | TBool | TPair e e@@ -50,7 +55,7 @@ deriving (Eq, Functor) data Proj = ProjLeft | ProjRight- deriving (Eq)+ deriving (Eq, Generic, NFData) data Op e = Plus e e | Mult e e@@ -69,7 +74,9 @@ | Impl e e deriving (Eq, Functor) -$(derive [makeNFData, makeArbitrary] [''Proj])++instance Arbitrary Proj where+ arbitrary = elements [ProjLeft,ProjRight] $(derive [makeFoldable, makeTraversable,
benchmark/DataTypes/Standard.hs view
@@ -1,12 +1,13 @@-{-# LANGUAGE TypeSynonymInstances, TemplateHaskell, DeriveDataTypeable #-}+{-# LANGUAGE TypeSynonymInstances, TemplateHaskell, DeriveDataTypeable,+DeriveGeneric, DeriveAnyClass #-} module DataTypes.Standard ( module DataTypes.Standard, module DataTypes ) where +import GHC.Generics (Generic)+ import DataTypes-import Data.Derive.NFData-import Data.DeriveTH import Data.Data import Control.DeepSeq @@ -15,15 +16,15 @@ data VType = VTInt | VTBool | VTPair VType VType- deriving (Eq,Typeable,Data)+ deriving (Eq,Typeable,Data, Generic, NFData) data SExpr = SInt Int | SBool Bool | SPair SExpr SExpr- deriving (Eq,Typeable,Data)+ deriving (Eq,Typeable,Data, Generic, NFData) data SProj = SProjLeft | SProjRight- deriving (Eq,Typeable,Data)+ deriving (Eq,Typeable,Data, Generic, NFData) data OExpr = OInt Int | OBool Bool@@ -36,7 +37,7 @@ | OAnd OExpr OExpr | ONot OExpr | OProj SProj OExpr- deriving (Eq,Typeable,Data)+ deriving (Eq,Typeable,Data, Generic, NFData) data PExpr = PInt Int | PBool Bool@@ -54,13 +55,13 @@ | PGt PExpr PExpr | POr PExpr PExpr | PImpl PExpr PExpr- deriving (Eq,Typeable,Data)+ deriving (Eq,Typeable,Data, Generic, NFData) data VHType = VHTInt | VHTBool | VHTPair VType VType | VHTFun VType VType- deriving (Eq,Typeable,Data)+ deriving (Eq,Typeable,Data, Generic, NFData) showBinOp :: String -> String -> String -> String showBinOp op x y = "("++ x ++ op ++ y ++ ")"@@ -88,5 +89,3 @@ show VTInt = "Int" show VTBool = "Bool" show (VTPair x y) = "(" ++ show x ++ "," ++ show y ++ ")"--$(derives [makeNFData] [''SProj,''SExpr,''OExpr,''PExpr,''VType])
benchmark/Functions/Comp/Desugar.hs view
@@ -6,7 +6,8 @@ UndecidableInstances, TypeOperators, ScopedTypeVariables,- TypeSynonymInstances #-}+ TypeSynonymInstances,+ ConstraintKinds #-} module Functions.Comp.Desugar where @@ -19,6 +20,8 @@ class (Functor e, Traversable f) => Desug f e where desugAlg :: Hom f e +$(derive [liftSum] [''Desug])+ desugExpr :: SugarExpr -> Expr desugExpr = desug @@ -33,8 +36,6 @@ {-# INLINE desug' #-} desug' = appHom' desugAlg -$(derive [liftSum] [''Desug])- instance (Value :<: v, Functor v) => Desug Value v where desugAlg = liftCxt @@ -60,7 +61,8 @@ desug2 :: (Functor f, Desug2 f g) => Term f -> Term g desug2 = cata desugAlg2 -$(derive [liftSum] [''Desug2])+instance (Desug2 f1 g, Desug2 f2 g) => Desug2 (f1 :+: f2) g where+ desugAlg2 = caseF desugAlg2 desugAlg2 instance (Value :<: v) => Desug2 Value v where desugAlg2 = inject
benchmark/Functions/Comp/Eval.hs view
@@ -6,33 +6,39 @@ UndecidableInstances, TypeOperators, ScopedTypeVariables,- TypeSynonymInstances #-}+ TypeSynonymInstances,+ ConstraintKinds,+ CPP #-} module Functions.Comp.Eval where import DataTypes.Comp import Functions.Comp.Desugar import Data.Comp-import Data.Comp.Ops-import Data.Comp.Thunk+import Data.Comp.Thunk hiding (eval, eval2) import Data.Comp.Derive++-- Control.Monad.Fail import is redundant since GHC 8.8.1+#if !MIN_VERSION_base(4,13,0)+import Control.Monad.Fail (MonadFail)+#endif+ import Control.Monad-import Data.Traversable -- evaluation with thunks class (Monad m, Traversable v) => EvalT e v m where evalTAlg :: AlgT m e v +$(derive [liftSum] [''EvalT])+ evalT :: (EvalT e v m, Functor e) => Term e -> m (Term v) evalT = nf . cata evalTAlg -$(derive [liftSum] [''EvalT])--instance (Monad m, Traversable v, Value :<: v) => EvalT Value v m where+instance (Monad m, Traversable v, Value :<: m :+: v) => EvalT Value v m where evalTAlg = inject -instance (Value :<: v, Traversable v, EqF v, Monad m) => EvalT Op v m where+instance (Value :<: (m :+: v), Value :<: v, Traversable v, EqF v, MonadFail m) => EvalT Op v m where evalTAlg (Plus x y) = thunk $ do VInt i <- whnfPr x VInt j <- whnfPr y@@ -65,7 +71,7 @@ ProjLeft -> x ProjRight -> y -instance (Value :<: v, Traversable v, Monad m) => EvalT Sugar v m where+instance (Value :<: (m :+: v), Value :<: v, Traversable v, MonadFail m) => EvalT Sugar v m where evalTAlg (Neg x) = thunk $ do VInt i <- whnfPr x return $ iVInt (-i)@@ -94,30 +100,30 @@ class Monad m => Eval e v m where evalAlg :: e (Term v) -> m (Term v) +$(derive [liftSum] [''Eval])+ eval :: (Traversable e, Eval e v m) => Term e -> m (Term v) eval = cataM evalAlg -$(derive [liftSum] [''Eval])- instance (Value :<: v, Monad m) => Eval Value v m where evalAlg = return . inject -coerceInt :: (Value :<: v, Monad m) => Term v -> m Int+coerceInt :: (Value :<: v, MonadFail m) => Term v -> m Int coerceInt t = case project t of Just (VInt i) -> return i _ -> fail "" -coerceBool :: (Value :<: v, Monad m) => Term v -> m Bool+coerceBool :: (Value :<: v, MonadFail m) => Term v -> m Bool coerceBool t = case project t of Just (VBool b) -> return b _ -> fail "" -coercePair :: (Value :<: v, Monad m) => Term v -> m (Term v, Term v)+coercePair :: (Value :<: v, MonadFail m) => Term v -> m (Term v, Term v) coercePair t = case project t of Just (VPair x y) -> return (x,y) _ -> fail "" -instance (Value :<: v, EqF v, Monad m) => Eval Op v m where+instance (Value :<: v, EqF v, MonadFail m) => Eval Op v m where evalAlg (Plus x y) = liftM2 (\ i j -> iVInt (i + j)) (coerceInt x) (coerceInt y) evalAlg (Mult x y) = liftM2 (\ i j -> iVInt (i * j)) (coerceInt x) (coerceInt y) evalAlg (If b x y) = liftM select (coerceBool b)@@ -131,7 +137,7 @@ ProjLeft -> x ProjRight -> y -instance (Value :<: v, Monad m) => Eval Sugar v m where+instance (Value :<: v, MonadFail m) => Eval Sugar v m where evalAlg (Neg x) = liftM (iVInt . negate) (coerceInt x) evalAlg (Minus x y) = liftM2 (\ i j -> iVInt (i - j)) (coerceInt x) (coerceInt y) evalAlg (Gt x y) = liftM2 (\ i j -> iVBool (i > j)) (coerceInt x) (coerceInt y)@@ -141,18 +147,18 @@ -- direct evaluation -class Monad m => EvalDir e m where+class MonadFail m => EvalDir e m where evalDir :: (Traversable f, EvalDir f m) => e (Term f) -> m ValueExpr +$(derive [liftSum] [''EvalDir])+ evalDirect :: (Traversable e, EvalDir e m) => Term e -> m ValueExpr-evalDirect = evalDir . unTerm+evalDirect (Term x) = evalDir x evalDirectE :: SugarExpr -> Err ValueExpr evalDirectE = evalDirect -$(derive [liftSum] [''EvalDir])--instance (Monad m) => EvalDir Value m where+instance (MonadFail m) => EvalDir Value m where evalDir (VInt i) = return $ iVInt i evalDir (VBool i) = return $ iVBool i evalDir (VPair x y) = liftM2 iVPair (evalDirect x) (evalDirect y)@@ -179,7 +185,7 @@ Just (VPair x y) -> return (x,y) _ -> fail "" -instance (Monad m) => EvalDir Op m where+instance (MonadFail m) => EvalDir Op m where evalDir (Plus x y) = liftM2 (\ i j -> iVInt (i + j)) (evalInt x) (evalInt y) evalDir (Mult x y) = liftM2 (\ i j -> iVInt (i * j)) (evalInt x) (evalInt y) evalDir (If b x y) = do @@ -194,7 +200,7 @@ ProjLeft -> x ProjRight -> y -instance (Monad m) => EvalDir Sugar m where+instance (MonadFail m) => EvalDir Sugar m where evalDir (Neg x) = liftM (iVInt . negate) (evalInt x) evalDir (Minus x y) = liftM2 (\ i j -> iVInt (i - j)) (evalInt x) (evalInt y) evalDir (Gt x y) = liftM2 (\ i j -> iVBool (i > j)) (evalInt x) (evalInt y)@@ -207,11 +213,11 @@ class Functor e => Eval2 e v where eval2Alg :: e (Term v) -> Term v +$(derive [liftSum] [''Eval2])+ eval2 :: (Functor e, Eval2 e v) => Term e -> Term v eval2 = cata eval2Alg -$(derive [liftSum] [''Eval2])- instance (Value :<: v) => Eval2 Value v where eval2Alg = inject @@ -258,13 +264,13 @@ class EvalDir2 e where evalDir2 :: (EvalDir2 f) => e (Term f) -> ValueExpr +$(derive [liftSum] [''EvalDir2])+ evalDirect2 :: (EvalDir2 e) => Term e -> ValueExpr-evalDirect2 = evalDir2 . unTerm+evalDirect2 (Term x) = evalDir2 x evalDirectE2 :: SugarExpr -> ValueExpr evalDirectE2 = evalDirect2--$(derive [liftSum] [''EvalDir2]) instance EvalDir2 Value where evalDir2 (VInt i) = iVInt i
benchmark/Functions/Comp/FreeVars.hs view
@@ -6,7 +6,8 @@ UndecidableInstances, TypeOperators, ScopedTypeVariables,- TypeSynonymInstances #-}+ TypeSynonymInstances,+ ConstraintKinds #-} module Functions.Comp.FreeVars where
+ benchmark/Functions/Comp/HOAS.hs view
@@ -0,0 +1,54 @@+{-# LANGUAGE+ TemplateHaskell,+ MultiParamTypeClasses,+ FlexibleInstances,+ FlexibleContexts,+ UndecidableInstances,+ TypeOperators,+ ScopedTypeVariables,+ TypeSynonymInstances #-}++module Functions.Comp.Desugar where++import DataTypes.Comp+import Data.Comp.ExpFunctor+import Data.Comp+import Data.Foldable+import Prelude hiding (foldr)++ex1 :: HOASExpr+ex1 = iLam (\x -> case project x of+ Just (VInt _) -> x + _ -> x `iPlus` x)+ex2 :: HOASExpr+ex2 = iLam (\x -> case x of+ Term t -> case proj t of+ Just (VInt _) -> x + _ -> x `iPlus` x)+ ++class Vars f where+ varsAlg :: Alg f Int++instance (Vars f, Vars g) => Vars (g :+: f) where+ varsAlg (Inl v) = varsAlg v+ varsAlg (Inr v) = varsAlg v++instance Vars Lam where+ varsAlg (Lam f) = f 1++instance Vars App where+ varsAlg = foldr (+) 0++instance Vars Value where+ varsAlg = foldr (+) 0++instance Vars Op where+ varsAlg = foldr (+) 0+++instance Vars Sugar where+ varsAlg = foldr (+) 0++vars :: (ExpFunctor f, Vars f) => Term f -> Int+vars = cataE varsAlg
benchmark/Functions/Comp/Inference.hs view
@@ -6,7 +6,9 @@ UndecidableInstances, TypeOperators, ScopedTypeVariables,- TypeSynonymInstances #-}+ TypeSynonymInstances,+ ConstraintKinds,+ CPP #-} module Functions.Comp.Inference where @@ -15,6 +17,11 @@ import Data.Comp import Data.Comp.Derive +-- Control.Monad.Fail import is redundant since GHC 8.8.1+#if !MIN_VERSION_base(4,13,0)+import Control.Monad.Fail (MonadFail)+#endif+ -- type inference class Monad m => InferType f t m where@@ -28,19 +35,19 @@ $(derive [liftSum] [''InferType]) -instance (ValueT :<: t, Monad m) => InferType Value t m where+instance (ValueT :<: t, MonadFail m) => InferType Value t m where inferTypeAlg (VInt _) = return $ inject TInt inferTypeAlg (VBool _) = return $ inject TBool inferTypeAlg (VPair x y) = return $ inject $ TPair x y -checkOp :: (g :<: f, Eq (g (Term f)), Monad m) =>+checkOp :: (g :<: f, Eq (g (Term f)), MonadFail m) => [g (Term f)] -> g (Term f) -> [Term f] -> m (Term f) checkOp exs et tys = if and (zipWith (\ f t -> maybe False (==f) (project t)) exs tys) then return (inject et) else fail"" -instance (ValueT :<: t, EqF t, Monad m) => InferType Op t m where+instance (ValueT :<: t, EqF t, MonadFail m) => InferType Op t m where inferTypeAlg (Plus x y) = checkOp [TInt,TInt] TInt [x ,y] inferTypeAlg (Mult x y) = checkOp [TInt,TInt] TInt [x ,y] inferTypeAlg (Lt x y) = checkOp [TInt,TInt] TBool [x ,y]@@ -57,7 +64,7 @@ ProjRight -> return x2 _ -> fail "" -instance (ValueT :<: t, EqF t, Monad m) => InferType Sugar t m where+instance (ValueT :<: t, EqF t, MonadFail m) => InferType Sugar t m where inferTypeAlg (Minus x y) = checkOp [TInt,TInt] TInt [x ,y] inferTypeAlg (Neg x) = checkOp [TInt] TInt [x] inferTypeAlg (Gt x y) = checkOp [TInt,TInt] TBool [x ,y]
benchmark/Functions/Standard/Eval.hs view
@@ -1,22 +1,29 @@+{-# LANGUAGE CPP #-}+ module Functions.Standard.Eval where import DataTypes.Standard import Functions.Standard.Desugar import Control.Monad -coerceInt :: (Monad m) => SExpr -> m Int+-- Control.Monad.Fail import is redundant since GHC 8.8.1+#if !MIN_VERSION_base(4,13,0)+import Control.Monad.Fail (MonadFail)+#endif++coerceInt :: (MonadFail m) => SExpr -> m Int coerceInt (SInt i) = return i coerceInt _ = fail "" -coerceBool :: (Monad m) => SExpr -> m Bool+coerceBool :: (MonadFail m) => SExpr -> m Bool coerceBool (SBool b) = return b coerceBool _ = fail "" -coercePair :: (Monad m) => SExpr -> m (SExpr,SExpr)+coercePair :: (MonadFail m) => SExpr -> m (SExpr,SExpr) coercePair (SPair x y) = return (x,y) coercePair _ = fail "" -eval :: (Monad m) => OExpr -> m SExpr+eval :: (MonadFail m) => OExpr -> m SExpr eval (OInt i) = return $ SInt i eval (OBool b) = return $ SBool b eval (OPair x y) = liftM2 SPair (eval x) (eval y)
benchmark/Functions/Standard/FreeVars.hs view
@@ -1,7 +1,7 @@ module Functions.Standard.FreeVars where import DataTypes.Standard-import Data.Generics.PlateDirect+import Data.Generics.Uniplate.Direct instance Uniplate PExpr where uniplate (PInt x) = plate PInt |- x
benchmark/Functions/Standard/Inference.hs view
@@ -1,17 +1,20 @@ module Functions.Standard.Inference where ++import Control.Monad.Fail import DataTypes.Standard-import Control.Monad+import Prelude hiding (fail)+import Control.Monad hiding (fail) import Functions.Standard.Desugar -checkOp :: (Monad m) => [VType] -> VType -> [OExpr] -> m VType+checkOp :: (MonadFail m) => [VType] -> VType -> [OExpr] -> m VType checkOp tys rety args = do argsty <- mapM inferType args if tys == argsty then return rety else fail "" -inferType :: (Monad m) => OExpr -> m VType+inferType :: (MonadFail m) => OExpr -> m VType inferType (OInt _) = return VTInt inferType (OBool _) = return VTBool inferType (OPair x y) = liftM2 VTPair (inferType x) (inferType y)
compdata.cabal view
@@ -1,22 +1,17 @@ Name: compdata-Version: 0.6.1.4+Version: 0.13.1 Synopsis: Compositional Data Types Description: - Based on Wouter Swierstra's Functional Pearl /Data types a la carte/- (Journal of Functional Programming, 18(4):423-436, 2008,- <http://dx.doi.org/10.1017/S0956796808006758>),- this package provides a framework for defining recursive- data types in a compositional manner. The fundamental idea of- /compositional data types/ (Workshop on Generic Programming, 83-94, 2011,- <http://dx.doi.org/10.1145/2036918.2036930>) is to separate the- signature of a data type- from the fixed point construction that produces its recursive- structure. By allowing to compose and decompose signatures,- compositional data types enable to combine data types in a flexible- way. The key point of Wouter Swierstra's original work is to define- functions on compositional data types in a compositional manner as- well by leveraging Haskell's type class machinery.+ This library implements the ideas of+ <http://dx.doi.org/10.1017/S0956796808006758 Data types a la carte>+ as outlined in the paper+ <http://dx.doi.org/10.1145/2036918.2036930 Compositional data types>. The+ purpose of this library is to allow the programmer to construct data+ types -- as well as the functions defined on them -- in a modular+ fashion. The underlying idea is to separate the signature of a data+ type from the fixed point construction that produces its recursive+ structure. Signatures can then be composed and decomposed freely. . Building on that foundation, this library provides additional extensions and (run-time) optimisations which make compositional data types@@ -26,10 +21,14 @@ suited for programming language implementations, especially, in an environment consisting of a family of tightly interwoven /domain-specific languages/. .- In concrete terms, this package provides the following features:+ In concrete terms, this library provides the following features: . * Compositional data types in the style of Wouter Swierstra's- Functional Pearl /Data types a la carte/.+ Functional Pearl /Data types a la carte/. The implementation of+ signature subsumption is based on the paper+ /Composing and Decomposing Data Types/ (Workshop on Generic+ Programming, 2014, to appear), which makes signature composition more+ flexible. . * Modular definition of functions on compositional data types through catamorphisms and anamorphisms as well as more structured@@ -69,209 +68,137 @@ to families of mutually recursive data types and (more generally) GADTs. This extension resides in the module "Data.Comp.Multi". .- * /Parametric compositional data types/ (Workshop on Mathematically- Structured Functional Programming, 3-24, 2012,- <http://dx.doi.org/10.4204/EPTCS.76.3>). All of the above is also- lifted to parametric data types, which enables support for- parametric higher-order abstract syntax (PHOAS). This extension- resides in the module "Data.Comp.Param".++ Examples of using (generalised) compositional data types are bundled+ with the package in the folder @examples@. .- * /Generalised parametric compositional data types/. All of the above is also- lifted to generalised parametric data types, which enables support for- typed parametric higher-order abstract syntax (PHOAS). This extension- resides in the module "Data.Comp.MultiParam".++ There are some supplementary packages, some of which were included+ in previous versions of this package: .- * Advanced recursion schemes derived from tree automata. These- recursion schemes allow for a higher degree of modularity and make- it possible to apply fusion. See /Modular Tree Automata/- (Mathematics of Program Construction, 263-299, 2012,- <http://dx.doi.org/10.1007/978-3-642-31113-0_14>).+ * <https://hackage.haskell.org/package/compdata-param compdata-param>:+ a parametric variant of compositional data types to deal with variable+ binders in a systematic way. .+ * <https://hackage.haskell.org/package/compdata-automata compdata-automata>:+ advanced recursion schemes derived from tree automata that allow for a+ higher degree of modularity and make it possible to apply fusion.+ .+ * <https://hackage.haskell.org/package/compdata-dags compdata-dags>:+ recursion schemes on directed acyclic graphs. - Examples of using (generalised) (parametric) compositional data types are- bundled with the package in the libray @examples@. -Category: Generics-License: BSD3-License-file: LICENSE-Author: Patrick Bahr, Tom Hvitved-Maintainer: paba@diku.dk-Build-Type: Simple+Category: Generics+License: BSD3+License-file: LICENSE+Author: Patrick Bahr, Tom Hvitved+Maintainer: paba@itu.dk+Build-Type: Simple Cabal-Version: >=1.9.2+bug-reports: https://github.com/pa-ba/compdata/issues extra-source-files:+ CHANGELOG.md -- test files- testsuite/tests/Data_Test.hs,- testsuite/tests/Data/Comp_Test.hs,- testsuite/tests/Data/Comp/Equality_Test.hs,- testsuite/tests/Data/Comp/Variables_Test.hs,- testsuite/tests/Data/Comp/Multi_Test.hs,- testsuite/tests/Data/Comp/Multi/Variables_Test.hs,- testsuite/tests/Data/Comp/Examples_Test.hs,- testsuite/tests/Data/Comp/Examples/Comp.hs,- testsuite/tests/Data/Comp/Examples/Multi.hs,- testsuite/tests/Data/Comp/Examples/Param.hs,- testsuite/tests/Data/Comp/Examples/MultiParam.hs,+ testsuite/tests/*.hs+ testsuite/tests/Data/*.hs+ testsuite/tests/Data/Comp/*.hs+ testsuite/tests/Data/Comp/Multi/*.hs+ testsuite/tests/Data/Comp/Examples/*.hs testsuite/tests/Test/Utils.hs -- benchmark files- benchmark/Test.hs- benchmark/Benchmark.hs- benchmark/DataTypes.hs- benchmark/Functions.hs- benchmark/DataTypes/Comp.hs- benchmark/DataTypes/Transform.hs- benchmark/DataTypes/Standard.hs- benchmark/Multi/DataTypes/Comp.hs- benchmark/Multi/Functions/Comp/Eval.hs- benchmark/Multi/Functions/Comp/Desugar.hs- benchmark/Transformations.hs- benchmark/Functions/Comp.hs- benchmark/Functions/Comp/Eval.hs- benchmark/Functions/Comp/Desugar.hs- benchmark/Functions/Comp/FreeVars.hs- benchmark/Functions/Comp/Inference.hs- benchmark/Functions/Standard/Eval.hs- benchmark/Functions/Standard/Desugar.hs- benchmark/Functions/Standard/FreeVars.hs- benchmark/Functions/Standard/Inference.hs- benchmark/Functions/Standard.hs+ benchmark/*.hs+ benchmark/DataTypes/*.hs+ benchmark/Functions/*.hs+ benchmark/Functions/Comp/*.hs+ benchmark/Functions/Standard/*.hs+ benchmark/Multi/DataTypes/*.hs+ benchmark/Multi/Functions/Comp/*.hs -- example files- examples/Examples/Common.hs- examples/Examples/Eval.hs- examples/Examples/EvalM.hs- examples/Examples/Desugar.hs- examples/Examples/Automata/Compiler.hs,- examples/Examples/Multi/Common.hs- examples/Examples/Multi/Eval.hs- examples/Examples/Multi/EvalI.hs- examples/Examples/Multi/EvalM.hs- examples/Examples/Multi/Desugar.hs- examples/Examples/Param/Lambda.hs- examples/Examples/Param/Names.hs- examples/Examples/Param/Graph.hs- examples/Examples/MultiParam/Lambda.hs- examples/Examples/MultiParam/FOL.hs+ examples/Examples/*.hs+ examples/Examples/Multi/*.hs library- Exposed-Modules: Data.Comp,- Data.Comp.Annotation,- Data.Comp.Sum,- Data.Comp.Term,- Data.Comp.Algebra,- Data.Comp.Equality,- Data.Comp.Ordering,- Data.Comp.DeepSeq,+ Exposed-Modules: Data.Comp+ Data.Comp.Annotation+ Data.Comp.Sum+ Data.Comp.Term+ Data.Comp.Algebra+ Data.Comp.Equality+ Data.Comp.Ordering+ Data.Comp.DeepSeq Data.Comp.Generic- Data.Comp.TermRewriting,- Data.Comp.Arbitrary,- Data.Comp.Show,- Data.Comp.Variables,- Data.Comp.Decompose,- Data.Comp.Unification,- Data.Comp.Derive,- Data.Comp.Matching,- Data.Comp.Desugar,- Data.Comp.Automata,- Data.Comp.Automata.Product,- Data.Comp.Number,- Data.Comp.Thunk,- Data.Comp.Ops,+ Data.Comp.TermRewriting+ Data.Comp.Arbitrary+ Data.Comp.Show+ Data.Comp.Render+ Data.Comp.Variables+ Data.Comp.Decompose+ Data.Comp.Unification+ Data.Comp.Derive+ Data.Comp.Derive.Utils+ Data.Comp.Matching+ Data.Comp.Desugar+ Data.Comp.Mapping+ Data.Comp.Thunk+ Data.Comp.Ops+ Data.Comp.Projection - Data.Comp.Multi,- Data.Comp.Multi.Term,- Data.Comp.Multi.Sum,- Data.Comp.Multi.HFunctor,- Data.Comp.Multi.HFoldable,- Data.Comp.Multi.HTraversable,- Data.Comp.Multi.Algebra,- Data.Comp.Multi.Annotation,- Data.Comp.Multi.Show,- Data.Comp.Multi.Equality,- Data.Comp.Multi.Ordering,- Data.Comp.Multi.Variables,- Data.Comp.Multi.Ops,- Data.Comp.Multi.Number,+ Data.Comp.Multi+ Data.Comp.Multi.Term+ Data.Comp.Multi.Sum+ Data.Comp.Multi.HFunctor+ Data.Comp.Multi.HFoldable+ Data.Comp.Multi.HTraversable+ Data.Comp.Multi.Algebra+ Data.Comp.Multi.Annotation+ Data.Comp.Multi.Show+ Data.Comp.Multi.Equality+ Data.Comp.Multi.Ordering+ Data.Comp.Multi.Variables+ Data.Comp.Multi.Ops+ Data.Comp.Multi.Mapping Data.Comp.Multi.Derive- Data.Comp.Multi.Generic,- Data.Comp.Multi.Desugar,-- Data.Comp.Param,- Data.Comp.Param.Term,- Data.Comp.Param.FreshM,- Data.Comp.Param.Sum,- Data.Comp.Param.Difunctor,- Data.Comp.Param.Ditraversable,- Data.Comp.Param.Algebra,- Data.Comp.Param.Annotation,- Data.Comp.Param.Ops- Data.Comp.Param.Equality- Data.Comp.Param.Ordering- Data.Comp.Param.Show- Data.Comp.Param.Derive,- Data.Comp.Param.Desugar- Data.Comp.Param.Thunk-- Data.Comp.MultiParam,- Data.Comp.MultiParam.Term,- Data.Comp.MultiParam.FreshM,- Data.Comp.MultiParam.Sum,- Data.Comp.MultiParam.HDifunctor,- Data.Comp.MultiParam.HDitraversable,- Data.Comp.MultiParam.Algebra,- Data.Comp.MultiParam.Annotation,- Data.Comp.MultiParam.Ops- Data.Comp.MultiParam.Equality- Data.Comp.MultiParam.Ordering- Data.Comp.MultiParam.Show- Data.Comp.MultiParam.Derive,- Data.Comp.MultiParam.Desugar+ Data.Comp.Multi.Generic+ Data.Comp.Multi.Desugar+ Data.Comp.Multi.Projection - Other-Modules: Data.Comp.Derive.Utils,- Data.Comp.Derive.Equality,- Data.Comp.Derive.Ordering,- Data.Comp.Derive.Arbitrary,- Data.Comp.Derive.Show,- Data.Comp.Derive.DeepSeq,- Data.Comp.Derive.SmartConstructors,- Data.Comp.Derive.SmartAConstructors,- Data.Comp.Derive.Foldable,- Data.Comp.Derive.Traversable,- Data.Comp.Derive.Injections,- Data.Comp.Derive.Projections,- Data.Comp.Derive.HaskellStrict,- Data.Comp.Automata.Product.Derive,+ Other-Modules: Data.Comp.SubsumeCommon+ Data.Comp.Derive.Equality+ Data.Comp.Derive.Ordering+ Data.Comp.Derive.Arbitrary+ Data.Comp.Derive.Show+ Data.Comp.Derive.DeepSeq+ Data.Comp.Derive.SmartConstructors+ Data.Comp.Derive.SmartAConstructors+ Data.Comp.Derive.Foldable+ Data.Comp.Derive.Traversable+ Data.Comp.Derive.HaskellStrict - Data.Comp.Multi.Derive.HFunctor,- Data.Comp.Multi.Derive.HFoldable,- Data.Comp.Multi.Derive.HTraversable,- Data.Comp.Multi.Derive.Equality,- Data.Comp.Multi.Derive.Ordering,- Data.Comp.Multi.Derive.Show,+ Data.Comp.Multi.Derive.HFunctor+ Data.Comp.Multi.Derive.HFoldable+ Data.Comp.Multi.Derive.HTraversable+ Data.Comp.Multi.Derive.Equality+ Data.Comp.Multi.Derive.Ordering+ Data.Comp.Multi.Derive.Show Data.Comp.Multi.Derive.SmartConstructors Data.Comp.Multi.Derive.SmartAConstructors- Data.Comp.Multi.Derive.Injections,- Data.Comp.Multi.Derive.Projections, - Data.Comp.Param.Derive.Difunctor,- Data.Comp.Param.Derive.Ditraversable,- Data.Comp.Param.Derive.Equality,- Data.Comp.Param.Derive.Ordering,- Data.Comp.Param.Derive.Show,- Data.Comp.Param.Derive.SmartConstructors,- Data.Comp.Param.Derive.SmartAConstructors,- Data.Comp.Param.Derive.Injections,- Data.Comp.Param.Derive.Projections, - Data.Comp.MultiParam.Derive.HDifunctor,- Data.Comp.MultiParam.Derive.Equality,- Data.Comp.MultiParam.Derive.Ordering,- Data.Comp.MultiParam.Derive.Show,- Data.Comp.MultiParam.Derive.SmartConstructors,- Data.Comp.MultiParam.Derive.SmartAConstructors,- Data.Comp.MultiParam.Derive.Injections,- Data.Comp.MultiParam.Derive.Projections - Build-Depends: base == 4.*, template-haskell, containers, mtl, QuickCheck >= 2, derive, deepseq, th-expand-syns, transformers++ Build-Depends: base >= 4.16 && < 4.19,+ QuickCheck >= 2.14.3 && < 2.15,+ containers >= 0.6.8 && < 0.7,+ deepseq >= 1.4 && < 1.6,+ template-haskell >= 2.17 && < 2.22,+ mtl >= 2.3.1 && < 2.4,+ transformers >= 0.6.1 && < 0.7,+ th-expand-syns >= 0.4.11 && < 0.5,+ tree-view >= 0.5.1 && < 0.6++ Default-Language: Haskell2010+ Default-Extensions: FlexibleContexts hs-source-dirs: src ghc-options: -W @@ -279,9 +206,89 @@ Test-Suite test Type: exitcode-stdio-1.0 Main-is: Data_Test.hs- hs-source-dirs: src testsuite/tests examples- Build-Depends: base == 4.*, template-haskell, containers, mtl, QuickCheck >= 2, HUnit, test-framework, test-framework-hunit, test-framework-quickcheck2, derive, th-expand-syns, deepseq, transformers+ hs-source-dirs: testsuite/tests examples src+ Build-Depends: base >= 4.16 && < 5, template-haskell, containers, mtl >= 2.2.1,+ QuickCheck >= 2, HUnit, test-framework, test-framework-hunit,+ test-framework-quickcheck2 >= 0.3, deepseq, transformers, th-expand-syns+ Default-Language: Haskell2010 + ghc-options: -W -Wno-incomplete-patterns+ Other-Modules:+ Data.Comp+ Data.Comp.Algebra+ Data.Comp.Annotation+ Data.Comp.Arbitrary+ Data.Comp.Derive+ Data.Comp.Derive.Arbitrary+ Data.Comp.Derive.DeepSeq+ Data.Comp.Derive.Equality+ Data.Comp.Derive.Foldable+ Data.Comp.Derive.HaskellStrict+ Data.Comp.Derive.Ordering+ Data.Comp.Derive.Show+ Data.Comp.Derive.SmartAConstructors+ Data.Comp.Derive.SmartConstructors+ Data.Comp.Derive.Traversable+ Data.Comp.Derive.Utils+ Data.Comp.Desugar+ Data.Comp.Equality+ Data.Comp.Equality_Test+ Data.Comp.Examples.Comp+ Data.Comp.Examples.Multi+ Data.Comp.Examples_Test+ Data.Comp.Generic+ Data.Comp.Mapping+ Data.Comp.Multi+ Data.Comp.Multi.Algebra+ Data.Comp.Multi.Annotation+ Data.Comp.Multi.Derive+ Data.Comp.Multi.Derive.Equality+ Data.Comp.Multi.Derive.HFoldable+ Data.Comp.Multi.Derive.HFunctor+ Data.Comp.Multi.Derive.HTraversable+ Data.Comp.Multi.Derive.Ordering+ Data.Comp.Multi.Derive.Show+ Data.Comp.Multi.Derive.SmartAConstructors+ Data.Comp.Multi.Derive.SmartConstructors+ Data.Comp.Multi.Desugar+ Data.Comp.Multi.Equality+ Data.Comp.Multi.Generic+ Data.Comp.Multi.HFoldable+ Data.Comp.Multi.HFunctor+ Data.Comp.Multi.HTraversable+ Data.Comp.Multi.Mapping+ Data.Comp.Multi.Ops+ Data.Comp.Multi.Ordering+ Data.Comp.Multi.Show+ Data.Comp.Multi.Sum+ Data.Comp.Multi.Term+ Data.Comp.Multi.Variables+ Data.Comp.Multi.Variables_Test+ Data.Comp.Multi_Test+ Data.Comp.Ops+ Data.Comp.Ordering+ Data.Comp.Show+ Data.Comp.SubsumeCommon+ Data.Comp.Subsume_Test+ Data.Comp.Sum+ Data.Comp.Term+ Data.Comp.Thunk+ Data.Comp.Variables+ Data.Comp.Variables_Test+ Data.Comp_Test+ Examples.Common+ Examples.Desugar+ Examples.Eval+ Examples.EvalM+ Examples.Thunk+ Examples.Multi.Common+ Examples.Multi.Desugar+ Examples.Multi.Eval+ Examples.Multi.EvalI+ Examples.Multi.EvalM+ Test.Utils++ Benchmark algebra Type: exitcode-stdio-1.0 Main-is: Benchmark.hs@@ -289,9 +296,55 @@ ghc-options: -W -O2 -- Disable short-cut fusion rules in order to compare optimised and unoptimised code. cpp-options: -DNO_RULES- Build-Depends: base == 4.*, template-haskell, containers, mtl, QuickCheck >= 2, derive, deepseq, criterion, random, uniplate, th-expand-syns, transformers-+ Build-Depends: base >= 4.16 && < 5, template-haskell, containers, mtl >= 2.2.1,+ QuickCheck >= 2, deepseq, criterion, random, uniplate, transformers,+ th-expand-syns+ Default-Language: Haskell2010+ Other-Modules:+ Data.Comp+ Data.Comp.Algebra+ Data.Comp.Annotation+ Data.Comp.Arbitrary+ Data.Comp.DeepSeq+ Data.Comp.Derive+ Data.Comp.Derive.Arbitrary+ Data.Comp.Derive.DeepSeq+ Data.Comp.Derive.Equality+ Data.Comp.Derive.Foldable+ Data.Comp.Derive.HaskellStrict+ Data.Comp.Derive.Ordering+ Data.Comp.Derive.Show+ Data.Comp.Derive.SmartAConstructors+ Data.Comp.Derive.SmartConstructors+ Data.Comp.Derive.Traversable+ Data.Comp.Derive.Utils+ Data.Comp.Equality+ Data.Comp.Generic+ Data.Comp.Mapping+ Data.Comp.Ops+ Data.Comp.Ordering+ Data.Comp.Show+ Data.Comp.SubsumeCommon+ Data.Comp.Sum+ Data.Comp.Term+ Data.Comp.Thunk+ Data.Comp.Variables+ DataTypes+ DataTypes.Comp+ DataTypes.Standard+ DataTypes.Transform+ Functions.Comp+ Functions.Comp.Desugar+ Functions.Comp.Eval+ Functions.Comp.FreeVars+ Functions.Comp.Inference+ Functions.Standard+ Functions.Standard.Desugar+ Functions.Standard.Eval+ Functions.Standard.FreeVars+ Functions.Standard.Inference source-repository head- type: hg- location: https://bitbucket.org/paba/compdata+ type: git+ location: https://github.com/pa-ba/compdata+
− examples/Examples/Automata/Compiler.hs
@@ -1,192 +0,0 @@-{-# LANGUAGE TemplateHaskell, FlexibleContexts, MultiParamTypeClasses,-TypeOperators, FlexibleInstances, UndecidableInstances,-ScopedTypeVariables, TypeSynonymInstances, GeneralizedNewtypeDeriving,-OverlappingInstances #-}--module Examples.Automata.Compiler where--import Data.Comp.Automata-import Data.Comp.Derive-import Data.Comp.Ops-import Data.Comp hiding (height)-import Data.Foldable-import Prelude hiding (foldl)--import Data.Set (Set, union, singleton, delete, member)-import qualified Data.Set as Set--import Data.Map (Map)-import qualified Data.Map as Map--type Var = String--data Val a = Const Int-data Op a = Plus a a- | Times a a-type Core = Op :+: Val-data Let a = Let Var a a- | Var Var--type CoreLet = Let :+: Core--data Sugar a = Neg a- | Minus a a--$(derive [makeFunctor, makeFoldable, makeTraversable, smartConstructors, makeShowF]- [''Val, ''Op, ''Let, ''Sugar])---class Eval f where- evalSt :: UpState f Int--$(derive [liftSum] [''Eval])--instance Eval Val where- evalSt (Const i) = i--instance Eval Op where- evalSt (Plus x y) = x + y- evalSt (Times x y) = x * y--type Addr = Int--data Instr = Acc Int- | Load Addr- | Store Addr- | Add Int- | Sub Int- | Mul Int- deriving (Show)--type Code = [Instr]--data MState = MState {- mRam :: Map Addr Int,- mAcc :: Int }--runCode :: Code -> MState -> MState-runCode [] = id-runCode (ins:c) = runCode c . step ins - where step (Acc i) s = s{mAcc = i}- step (Load a) s = case Map.lookup a (mRam s) of- Nothing -> error $ "memory cell " ++ show a ++ " is not set"- Just n -> s {mAcc = n}- step (Store a) s = s {mRam = Map.insert a (mAcc s) (mRam s)}- step (Add a) s = exec (+) a s- step (Sub a) s = exec (-) a s- step (Mul a) s = exec (*) a s- exec op a s = case Map.lookup a (mRam s) of- Nothing -> error $ "memory cell " ++ show a ++ " is not set"- Just n -> s {mAcc = mAcc s `op` n}---runCode' :: Code -> Int-runCode' c = mAcc $ runCode c MState{mRam = Map.empty, mAcc = error "accumulator is not set"}----- | Defines the height of an expression.-heightSt :: Foldable f => UpState f Int-heightSt t = foldl max 0 t + 1--tmpAddrSt :: Foldable f => UpState f Int-tmpAddrSt = (+1) . heightSt---newtype VarAddr = VarAddr {varAddr :: Int} deriving (Eq, Show, Num)--class VarAddrSt f where- varAddrSt :: DownState f VarAddr- -instance (VarAddrSt f, VarAddrSt g) => VarAddrSt (f :+: g) where- varAddrSt (q,Inl x) = varAddrSt (q, x)- varAddrSt (q,Inr x) = varAddrSt (q, x)--instance VarAddrSt Let where- varAddrSt (d, Let _ _ x) = x `Map.singleton` (d + 2)- varAddrSt _ = Map.empty- -instance VarAddrSt f where- varAddrSt _ = Map.empty---type Bind = Map Var Int--bindSt :: (Let :<: f,VarAddr :< q) => DDownState f q Bind-bindSt t = case proj t of- Just (Let v _ e) -> Map.singleton e q'- where q' = Map.insert v (varAddr above) above- _ -> Map.empty---- | Defines the code that an expression is compiled to. It depends on--- an integer state that denotes the height of the current node.-class CodeSt f q where- codeSt :: DUpState f q Code--instance (CodeSt f q, CodeSt g q) => CodeSt (f :+: g) q where- codeSt (Inl x) = codeSt x- codeSt (Inr x) = codeSt x- --instance CodeSt Val q where- codeSt (Const i) = [Acc i]--instance (Int :< q) => CodeSt Op q where- codeSt (Plus x y) = below x ++ [Store i] ++ below y ++ [Add i]- where i = below y- codeSt (Times x y) = below x ++ [Store i] ++ below y ++ [Mul i]- where i = below y--instance (VarAddr :< q, Bind :< q) => CodeSt Let q where- codeSt (Let _ b e) = below b ++ [Store i] ++ below e- where i = varAddr above- codeSt (Var v) = case Map.lookup v above of- Nothing -> error $ "unbound variable " ++ v- Just i -> [Load i]--compile' :: (CodeSt f (Code,Int), Foldable f, Functor f) => Term f -> Code-compile' = fst . runDUpState (codeSt `prodDUpState` dUpState tmpAddrSt)---exComp' = compile' (iConst 2 `iPlus` iConst 3 :: Term Core)----compile :: (CodeSt f ((Code,Int),(Bind,VarAddr)), Traversable f, Functor f, Let :<: f, VarAddrSt f)- => Term f -> Code-compile = fst . runDState - (codeSt `prodDUpState` dUpState tmpAddrSt)- (bindSt `prodDDownState` dDownState varAddrSt)- (Map.empty, VarAddr 1)- --exComp = compile (iLet "x" (iLet "x" (iConst 5) (iConst 10 `iPlus` iVar "x")) (iConst 2 `iPlus` iVar "x") :: Term CoreLet)---- | Defines the set of free variables-class VarsSt f where- varsSt :: UpState f (Set Var)--$(derive [liftSum] [''VarsSt])--instance VarsSt Val where- varsSt _ = Set.empty--instance VarsSt Op where- varsSt (Plus x y) = x `union` y- varsSt (Times x y) = x `union` y--instance VarsSt Let where- varsSt (Var v) = singleton v- varsSt (Let v x y) = (if v `member` y then x else Set.empty) `union` delete v y---- | Stateful homomorphism that removes unnecessary let bindings.-remLetHom :: (Set Var :< q, Let :<: f, Functor f) => QHom f q f-remLetHom t = case proj t of- Just (Let v _ y) - | not (v `member` below y) -> Hole y- _ -> simpCxt t---- | Removes unnecessary let bindings.-remLet :: (Let :<: f, Functor f, VarsSt f) => Term f -> Term f-remLet = runUpHom varsSt remLetHom--exLet = remLet (iLet "x" (iConst 3) (iConst 2 `iPlus` iVar "y") :: Term CoreLet)
examples/Examples/Common.hs view
@@ -1,4 +1,6 @@ {-# LANGUAGE TemplateHaskell, TypeOperators #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE DeriveFunctor #-} -------------------------------------------------------------------------------- -- | -- Module : Examples.Common@@ -21,12 +23,14 @@ -- Signature for values and operators data Value a = Const Int | Pair a a+ deriving Functor data Op a = Add a a | Mult a a | Fst a | Snd a+ deriving Functor -- Signature for the simple expression language type Sig = Op :+: Value -- Derive boilerplate code using Template Haskell-$(derive [makeFunctor, makeTraversable, makeFoldable,+$(derive [makeTraversable, makeFoldable, makeEqF, makeShowF, smartConstructors, smartAConstructors] [''Value, ''Op])
examples/Examples/Desugar.hs view
@@ -1,6 +1,7 @@ {-# LANGUAGE TemplateHaskell, TypeOperators, MultiParamTypeClasses, FlexibleInstances, FlexibleContexts, UndecidableInstances,- OverlappingInstances #-}+ ConstraintKinds #-}+{-# LANGUAGE DeriveFunctor #-} -------------------------------------------------------------------------------- -- | -- Module : Examples.Desugar@@ -31,6 +32,7 @@ -- Signature for syntactic sugar data Sugar a = Neg a | Swap a+ deriving Functor -- Source position information (line number, column number) data Pos = Pos Int Int@@ -47,7 +49,7 @@ type SigP' = Sugar :&: Pos :+: Op :&: Pos :+: Value :&: Pos -- Derive boilerplate code using Template Haskell-$(derive [makeFunctor, makeTraversable, makeFoldable,+$(derive [makeTraversable, makeFoldable, makeEqF, makeShowF, makeOrdF, smartConstructors, smartAConstructors] [''Sugar])
examples/Examples/Eval.hs view
@@ -1,6 +1,6 @@ {-# LANGUAGE TemplateHaskell, TypeOperators, MultiParamTypeClasses, FlexibleInstances, FlexibleContexts, UndecidableInstances,- OverlappingInstances #-}+ ConstraintKinds #-} -------------------------------------------------------------------------------- -- | -- Module : Examples.Eval@@ -35,10 +35,10 @@ eval :: (Functor f, Eval f v) => Term f -> Term v eval = cata evalAlg -instance (f :<: v) => Eval f v where+instance {-# OVERLAPPABLE #-} (f :<: v) => Eval f v where evalAlg = inject -- default instance -instance (Value :<: v) => Eval Op v where+instance {-# OVERLAPPABLE #-} (Value :<: v) => Eval Op v where evalAlg (Add x y) = iConst $ projC x + projC y evalAlg (Mult x y) = iConst $ projC x * projC y evalAlg (Fst x) = fst $ projP x
examples/Examples/EvalM.hs view
@@ -1,6 +1,6 @@ {-# LANGUAGE TemplateHaskell, TypeOperators, MultiParamTypeClasses, FlexibleInstances, FlexibleContexts, UndecidableInstances,- OverlappingInstances #-}+ ConstraintKinds #-} -------------------------------------------------------------------------------- -- | -- Module : Examples.EvalM@@ -35,10 +35,10 @@ evalM :: (Traversable f, EvalM f v) => Term f -> Maybe (Term v) evalM = cataM evalAlgM -instance (f :<: v) => EvalM f v where+instance {-# OVERLAPPABLE #-} (f :<: v) => EvalM f v where evalAlgM = return . inject -- default instance -instance (Value :<: v) => EvalM Op v where+instance {-# OVERLAPPABLE #-} (Value :<: v) => EvalM Op v where evalAlgM (Add x y) = do n1 <- projC x n2 <- projC y return $ iConst $ n1 + n2
examples/Examples/Multi/Desugar.hs view
@@ -1,6 +1,6 @@ {-# LANGUAGE TemplateHaskell, TypeOperators, MultiParamTypeClasses, FlexibleInstances, FlexibleContexts, UndecidableInstances, GADTs,- IncoherentInstances #-}+ ConstraintKinds #-} -------------------------------------------------------------------------------- -- | -- Module : Examples.Multi.Desugar
examples/Examples/Multi/Eval.hs view
@@ -1,6 +1,6 @@ {-# LANGUAGE TemplateHaskell, TypeOperators, MultiParamTypeClasses, FlexibleInstances, FlexibleContexts, UndecidableInstances, GADTs,- OverlappingInstances #-}+ ConstraintKinds #-} -------------------------------------------------------------------------------- -- | -- Module : Examples.Multi.Eval@@ -34,10 +34,10 @@ eval :: (HFunctor f, Eval f v) => Term f :-> Term v eval = cata evalAlg -instance (f :<: v) => Eval f v where+instance {-# OVERLAPPABLE #-} (f :<: v) => Eval f v where evalAlg = inject -- default instance -instance (Value :<: v) => Eval Op v where+instance {-# OVERLAPPABLE #-} (Value :<: v) => Eval Op v where evalAlg (Add x y) = iConst $ projC x + projC y evalAlg (Mult x y) = iConst $ projC x * projC y evalAlg (Fst x) = fst $ projP x
examples/Examples/Multi/EvalM.hs view
@@ -1,6 +1,6 @@ {-# LANGUAGE TemplateHaskell, TypeOperators, MultiParamTypeClasses, FlexibleInstances, FlexibleContexts, UndecidableInstances, GADTs,- OverlappingInstances #-}+ ConstraintKinds #-} -------------------------------------------------------------------------------- -- | -- Module : Examples.Multi.EvalM@@ -34,10 +34,10 @@ evalM :: (HTraversable f, EvalM f v) => Term f i -> Maybe (Term v i) evalM = cataM evalAlgM -instance (f :<: v) => EvalM f v where+instance {-# OVERLAPPABLE #-} (f :<: v) => EvalM f v where evalAlgM = return . inject -- default instance -instance (Value :<: v) => EvalM Op v where+instance {-# OVERLAPPABLE #-} (Value :<: v) => EvalM Op v where evalAlgM (Add x y) = do n1 <- projC x n2 <- projC y return $ iConst $ n1 + n2
− examples/Examples/MultiParam/FOL.hs
@@ -1,436 +0,0 @@-{-# LANGUAGE TemplateHaskell, TypeOperators, FlexibleInstances,- FlexibleContexts, UndecidableInstances, GADTs, KindSignatures,- OverlappingInstances, TypeSynonymInstances, EmptyDataDecls #-}------------------------------------------------------------------------------------ |--- Module : Examples.MultiParam.FOL--- Copyright : (c) 2011 Patrick Bahr, Tom Hvitved--- License : BSD3--- Maintainer : Tom Hvitved <hvitved@diku.dk>--- Stability : experimental--- Portability : non-portable (GHC Extensions)------ First-Order Logic a la Carte------ This example illustrates how to implement First-Order Logic a la Carte--- (Knowles, The Monad.Reader Issue 11, '08) using Generalised Parametric--- Compositional Data Types.------ Rather than using a fixed domain 'Term' for binders as Knowles, our encoding--- uses a mutually recursive data structure for terms and formulae. This makes--- terms modular too, and hence we only introduce variables when they are--- actually needed in stage 5.--------------------------------------------------------------------------------------module Examples.MultiParam.FOL where--import Data.Comp.MultiParam hiding (Var)-import qualified Data.Comp.MultiParam as MP-import Data.Comp.MultiParam.Show ()-import Data.Comp.MultiParam.Derive-import Data.Comp.MultiParam.FreshM (Name, withName, evalFreshM)-import Data.List (intercalate)-import Data.Maybe-import Control.Monad.State-import Control.Monad.Reader---- Phantom types indicating whether a (recursive) term is a formula or a term-data TFormula-data TTerm---- Terms-data Const :: (* -> *) -> (* -> *) -> * -> * where- Const :: String -> [e TTerm] -> Const a e TTerm-data Var :: (* -> *) -> (* -> *) -> * -> * where- Var :: String -> Var a e TTerm---- Formulae-data TT :: (* -> *) -> (* -> *) -> * -> * where- TT :: TT a e TFormula-data FF :: (* -> *) -> (* -> *) -> * -> * where- FF :: FF a e TFormula-data Atom :: (* -> *) -> (* -> *) -> * -> * where- Atom :: String -> [e TTerm] -> Atom a e TFormula-data NAtom :: (* -> *) -> (* -> *) -> * -> * where- NAtom :: String -> [e TTerm] -> NAtom a e TFormula-data Not :: (* -> *) -> (* -> *) -> * -> * where- Not :: e TFormula -> Not a e TFormula-data Or :: (* -> *) -> (* -> *) -> * -> * where- Or :: e TFormula -> e TFormula -> Or a e TFormula-data And :: (* -> *) -> (* -> *) -> * -> * where- And :: e TFormula -> e TFormula -> And a e TFormula-data Impl :: (* -> *) -> (* -> *) -> * -> * where- Impl :: e TFormula -> e TFormula -> Impl a e TFormula-data Exists :: (* -> *) -> (* -> *) -> * -> * where- Exists :: (a TTerm -> e TFormula) -> Exists a e TFormula-data Forall :: (* -> *) -> (* -> *) -> * -> * where- Forall :: (a TTerm -> e TFormula) -> Forall a e TFormula--$(derive [makeHDifunctor, smartConstructors]- [''Const, ''Var, ''TT, ''FF, ''Atom, ''NAtom,- ''Not, ''Or, ''And, ''Impl, ''Exists, ''Forall])------------------------------------------------------------------------------------- (Custom) pretty printing of terms and formulae-----------------------------------------------------------------------------------instance ShowHD Const where- showHD (Const f t) = do ts <- mapM unK t- return $ f ++ "(" ++ intercalate ", " ts ++ ")"--instance ShowHD Var where- showHD (Var x) = return x--instance ShowHD TT where- showHD TT = return "true"--instance ShowHD FF where- showHD FF = return "false"--instance ShowHD Atom where- showHD (Atom p t) = do ts <- mapM unK t- return $ p ++ "(" ++ intercalate ", " ts ++ ")"--instance ShowHD NAtom where- showHD (NAtom p t) = do ts <- mapM unK t- return $ "not " ++ p ++ "(" ++ intercalate ", " ts ++ ")"--instance ShowHD Not where- showHD (Not (K f)) = liftM (\x -> "not (" ++ x ++ ")") f--instance ShowHD Or where- showHD (Or (K f1) (K f2)) =- liftM2 (\x y -> "(" ++ x ++ ") or (" ++ y ++ ")") f1 f2--instance ShowHD And where- showHD (And (K f1) (K f2)) =- liftM2 (\x y -> "(" ++ x ++ ") and (" ++ y ++ ")") f1 f2--instance ShowHD Impl where- showHD (Impl (K f1) (K f2)) =- liftM2 (\x y -> "(" ++ x ++ ") -> (" ++ y ++ ")") f1 f2--instance ShowHD Exists where- showHD (Exists f) =- withName (\x -> do b <- unK (f x)- return $ "exists " ++ show x ++ ". " ++ b)--instance ShowHD Forall where- showHD (Forall f) =- withName (\x -> do b <- unK (f x)- return $ "forall " ++ show x ++ ". " ++ b)------------------------------------------------------------------------------------- Stage 0-----------------------------------------------------------------------------------type Input = Const :+:- TT :+: FF :+: Atom :+: Not :+: Or :+: And :+: Impl :+:- Exists :+: Forall--foodFact :: Term Input TFormula-foodFact = Term $- iExists (\p -> iAtom "Person" [p] `iAnd`- iForall (\f -> iAtom "Food" [f] `iImpl`- iAtom "Eats" [p,f])) `iImpl`- iNot (iExists $ \f -> iAtom "Food" [f] `iAnd`- iNot (iExists $ \p -> iAtom "Person" [p] `iAnd`- iAtom "Eats" [p,f]))------------------------------------------------------------------------------------- Stage 1: Eliminate Implications-----------------------------------------------------------------------------------type Stage1 = Const :+:- TT :+: FF :+: Atom :+: Not :+: Or :+: And :+: Exists :+: Forall--class HDifunctor f => ElimImp f where- elimImpHom :: Hom f Stage1--$(derive [liftSum] [''ElimImp])--elimImp :: Term Input :-> Term Stage1-elimImp (Term t) = Term (appHom elimImpHom t)--instance (HDifunctor f, f :<: Stage1) => ElimImp f where- elimImpHom = simpCxt . inj--instance ElimImp Impl where- elimImpHom (Impl f1 f2) = iNot (Hole f1) `iOr` (Hole f2)--foodFact1 :: Term Stage1 TFormula-foodFact1 = elimImp foodFact------------------------------------------------------------------------------------- Stage 2: Move Negation Inwards-----------------------------------------------------------------------------------type Stage2 = Const :+:- TT :+: FF :+: Atom :+: NAtom :+: Or :+: And :+: Exists :+: Forall--class HDifunctor f => Dualize f where- dualizeHom :: f a (Cxt h Stage2 a b) :-> Cxt h Stage2 a b--$(derive [liftSum] [''Dualize])--dualize :: Trm Stage2 a :-> Trm Stage2 a-dualize = appHom (dualizeHom . hfmap Hole)--instance Dualize Const where- dualizeHom (Const f t) = iConst f t--instance Dualize TT where- dualizeHom TT = iFF--instance Dualize FF where- dualizeHom FF = iTT--instance Dualize Atom where- dualizeHom (Atom p t) = iNAtom p t--instance Dualize NAtom where- dualizeHom (NAtom p t) = iAtom p t--instance Dualize Or where- dualizeHom (Or f1 f2) = f1 `iAnd` f2--instance Dualize And where- dualizeHom (And f1 f2) = f1 `iOr` f2--instance Dualize Exists where- dualizeHom (Exists f) = inject $ Forall f--instance Dualize Forall where- dualizeHom (Forall f) = inject $ Exists f--class PushNot f where- pushNotAlg :: Alg f (Trm Stage2 a)--$(derive [liftSum] [''PushNot])--pushNotInwards :: Term Stage1 :-> Term Stage2-pushNotInwards t = Term (cata pushNotAlg t)--instance (HDifunctor f, f :<: Stage2) => PushNot f where- pushNotAlg = inject . hdimap MP.Var id -- default--instance PushNot Not where- pushNotAlg (Not f) = dualize f--foodFact2 :: Term Stage2 TFormula-foodFact2 = pushNotInwards foodFact1------------------------------------------------------------------------------------- Stage 4: Skolemization-----------------------------------------------------------------------------------type Stage4 = Const :+:- TT :+: FF :+: Atom :+: NAtom :+: Or :+: And :+: Forall--type Unique = Int-data UniqueSupply = UniqueSupply Unique UniqueSupply UniqueSupply--initialUniqueSupply :: UniqueSupply-initialUniqueSupply = genSupply 1- where genSupply n = UniqueSupply n (genSupply (2 * n))- (genSupply (2 * n + 1))--splitUniqueSupply :: UniqueSupply -> (UniqueSupply, UniqueSupply)-splitUniqueSupply (UniqueSupply _ l r) = (l,r)--getUnique :: UniqueSupply -> (Unique, UniqueSupply)-getUnique (UniqueSupply n l _) = (n,l)--type Supply = State UniqueSupply-type S a = ReaderT [Trm Stage4 a TTerm] Supply--evalS :: S a b -> [Trm Stage4 a TTerm] -> UniqueSupply -> b-evalS m env = evalState (runReaderT m env)--fresh :: S a Int-fresh = do supply <- get- let (uniq,rest) = getUnique supply- put rest- return uniq--freshes :: S a UniqueSupply-freshes = do supply <- get- let (l,r) = splitUniqueSupply supply- put r- return l--class Skolem f where- skolemAlg :: AlgM' (S a) f (Trm Stage4 a)--$(derive [liftSum] [''Skolem])--skolemize :: Term Stage2 :-> Term Stage4-skolemize f = Term (evalState (runReaderT (cataM' skolemAlg f) [])- initialUniqueSupply)--instance Skolem Const where- skolemAlg (Const f t) = liftM (iConst f) $ mapM getCompose t--instance Skolem TT where- skolemAlg TT = return iTT--instance Skolem FF where- skolemAlg FF = return iFF--instance Skolem Atom where- skolemAlg (Atom p t) = liftM (iAtom p) $ mapM getCompose t--instance Skolem NAtom where- skolemAlg (NAtom p t) = liftM (iNAtom p) $ mapM getCompose t--instance Skolem Or where- skolemAlg (Or (Compose f1) (Compose f2)) = liftM2 iOr f1 f2--instance Skolem And where- skolemAlg (And (Compose f1) (Compose f2)) = liftM2 iAnd f1 f2--instance Skolem Forall where- skolemAlg (Forall f) = do- supply <- freshes- xs <- ask- return $ iForall $ \x -> evalS (getCompose $ f x) (x : xs) supply--instance Skolem Exists where- skolemAlg (Exists f) = do- uniq <- fresh- xs <- ask- getCompose $ f (iConst ("Skol" ++ show uniq) xs)--foodFact4 :: Term Stage4 TFormula-foodFact4 = skolemize foodFact2------------------------------------------------------------------------------------- Stage 5: Prenex Normal Form-----------------------------------------------------------------------------------type Stage5 = Const :+: Var :+:- TT :+: FF :+: Atom :+: NAtom :+: Or :+: And--class Prenex f where- prenexAlg :: AlgM' (S a) f (Trm Stage5 a)--$(derive [liftSum] [''Prenex])--prenex :: Term Stage4 :-> Term Stage5-prenex f = Term (evalState (runReaderT (cataM' prenexAlg f) [])- initialUniqueSupply)--instance Prenex Const where- prenexAlg (Const f t) = liftM (iConst f) $ mapM getCompose t--instance Prenex TT where- prenexAlg TT = return iTT--instance Prenex FF where- prenexAlg FF = return iFF--instance Prenex Atom where- prenexAlg (Atom p t) = liftM (iAtom p) $ mapM getCompose t--instance Prenex NAtom where- prenexAlg (NAtom p t) = liftM (iNAtom p) $ mapM getCompose t--instance Prenex Or where- prenexAlg (Or (Compose f1) (Compose f2)) = liftM2 iOr f1 f2--instance Prenex And where- prenexAlg (And (Compose f1) (Compose f2)) = liftM2 iAnd f1 f2--instance Prenex Forall where- prenexAlg (Forall f) = do uniq <- fresh- getCompose $ f (iVar ('x' : show uniq))--foodFact5 :: Term Stage5 TFormula-foodFact5 = prenex foodFact4------------------------------------------------------------------------------------- Stage 6: Conjunctive Normal Form-----------------------------------------------------------------------------------type Literal a = Trm (Const :+: Var :+: Atom :+: NAtom) a-newtype Clause a i = Clause {unClause :: [Literal a i]} -- implicit disjunction-newtype CNF a i = CNF {unCNF :: [Clause a i]} -- implicit conjunction--instance (HDifunctor f, ShowHD f) => Show (Trm f Name i) where- show = evalFreshM . showHD . toCxt--instance Show (Clause Name i) where- show c = intercalate " or " $ map show $ unClause c--instance Show (CNF Name i) where- show c = intercalate "\n" $ map show $ unCNF c--class ToCNF f where- cnfAlg :: f (CNF a) (CNF a) i -> [Clause a i]--$(derive [liftSum] [''ToCNF])--cnf :: Term Stage5 :-> CNF a-cnf = cata (CNF . cnfAlg)--instance ToCNF Const where- cnfAlg (Const f t) =- [Clause [iConst f (map (head . unClause . head . unCNF) t)]]--instance ToCNF Var where- cnfAlg (Var x) = [Clause [iVar x]]--instance ToCNF TT where- cnfAlg TT = []--instance ToCNF FF where- cnfAlg FF = [Clause []]--instance ToCNF Atom where- cnfAlg (Atom p t) =- [Clause [iAtom p (map (head . unClause . head . unCNF) t)]]--instance ToCNF NAtom where- cnfAlg (NAtom p t) =- [Clause [iNAtom p (map (head . unClause . head . unCNF) t)]]--instance ToCNF And where- cnfAlg (And f1 f2) = unCNF f1 ++ unCNF f2--instance ToCNF Or where- cnfAlg (Or f1 f2) =- [Clause (x ++ y) | Clause x <- unCNF f1, Clause y <- unCNF f2]--foodFact6 :: CNF a TFormula-foodFact6 = cnf foodFact5------------------------------------------------------------------------------------- Stage 7: Implicative Normal Form-----------------------------------------------------------------------------------type T = Const :+: Var :+: Atom :+: NAtom-newtype IClause a i = IClause ([Trm T a i], -- implicit conjunction- [Trm T a i]) -- implicit disjunction-newtype INF a i = INF [IClause a i] -- implicit conjunction--instance Show (IClause Name i) where- show (IClause (cs,ds)) = let cs' = intercalate " and " $ map show cs- ds' = intercalate " or " $ map show ds- in "(" ++ cs' ++ ") -> (" ++ ds' ++ ")"--instance Show (INF Name i) where- show (INF fs) = intercalate "\n" $ map show fs--inf :: CNF a TFormula -> INF a TFormula-inf (CNF f) = INF $ map (toImpl . unClause) f- where toImpl :: [Literal a TFormula] -> IClause a TFormula- toImpl disj = IClause ([iAtom p t | NAtom p t <- mapMaybe proj1 disj],- [inject t | t <- mapMaybe proj2 disj])- proj1 :: NatM Maybe (Trm T a) (NAtom a (Trm T a))- proj1 = project- proj2 :: NatM Maybe (Trm T a) (Atom a (Trm T a))- proj2 = project--foodFact7 :: INF a TFormula-foodFact7 = inf foodFact6
− examples/Examples/MultiParam/Lambda.hs
@@ -1,106 +0,0 @@-{-# LANGUAGE TemplateHaskell, TypeOperators, MultiParamTypeClasses,- FlexibleInstances, FlexibleContexts, UndecidableInstances,- OverlappingInstances, Rank2Types, GADTs, KindSignatures,- ScopedTypeVariables, TypeFamilies #-}------------------------------------------------------------------------------------ |--- Module : Examples.MultiParam.Lambda--- Copyright : (c) 2011 Patrick Bahr, Tom Hvitved--- License : BSD3--- Maintainer : Tom Hvitved <hvitved@diku.dk>--- Stability : experimental--- Portability : non-portable (GHC Extensions)------ Tagless (monadic) interpretation of extended lambda calculus--------------------------------------------------------------------------------------module Examples.MultiParam.Lambda where--import Data.Comp.MultiParam-import Data.Comp.MultiParam.Show ()-import Data.Comp.MultiParam.Equality ()-import Data.Comp.MultiParam.Derive-import Control.Monad (liftM2)-import Control.Monad.Error (MonadError, throwError)--data Lam :: (* -> *) -> (* -> *) -> * -> * where- Lam :: (a i -> b j) -> Lam a b (i -> j)-data App :: (* -> *) -> (* -> *) -> * -> * where- App :: b (i -> j) -> b i -> App a b j-data Const :: (* -> *) -> (* -> *) -> * -> * where- Const :: Int -> Const a b Int-data Plus :: (* -> *) -> (* -> *) -> * -> * where- Plus :: b Int -> b Int -> Plus a b Int-data Err :: (* -> *) -> (* -> *) -> * -> * where- Err :: Err a b i-type Sig = Lam :+: App :+: Const :+: Plus :+: Err--$(derive [smartConstructors, makeHDifunctor, makeShowHD, makeEqHD]- [''Lam, ''App, ''Const, ''Plus, ''Err])---- * Tagless interpretation-class Eval f where- evalAlg :: f I I i -> i -- I . evalAlg :: Alg f I is the actual algebra--$(derive [liftSum] [''Eval])--eval :: (HDifunctor f, Eval f) => Term f i -> i-eval = unI . cata (I . evalAlg)--instance Eval Lam where- evalAlg (Lam f) = unI . f . I--instance Eval App where- evalAlg (App (I f) (I x)) = f x--instance Eval Const where- evalAlg (Const n) = n--instance Eval Plus where- evalAlg (Plus (I x) (I y)) = x + y--instance Eval Err where- evalAlg Err = error "error"---- * Tagless monadic interpretation-type family Sem (m :: * -> *) i-type instance Sem m (i -> j) = Sem m i -> m (Sem m j)-type instance Sem m Int = Int--newtype M m i = M {unM :: m (Sem m i)}--class Monad m => EvalM m f where- evalMAlg :: f (M m) (M m) i -> m (Sem m i) -- M . evalMAlg :: Alg f (M m)--$(derive [liftSum] [''EvalM])--evalM :: (Monad m, HDifunctor f, EvalM m f) => Term f i -> m (Sem m i)-evalM = unM . cata (M . evalMAlg)--instance Monad m => EvalM m Lam where- evalMAlg (Lam f) = return $ unM . f . M . return--instance Monad m => EvalM m App where- evalMAlg (App (M mf) (M mx)) = do f <- mf; f =<< mx- -instance Monad m => EvalM m Const where- evalMAlg (Const n) = return n--instance Monad m => EvalM m Plus where- evalMAlg (Plus (M mx) (M my)) = liftM2 (+) mx my--instance MonadError String m => EvalM m Err where- evalMAlg Err = throwError "error" -- 'throwError' rather than 'error'--e :: Term Sig Int-e = Term ((iLam $ \x -> (iLam (\y -> y `iPlus` x) `iApp` iConst 3)) `iApp` iConst 2)--v :: Either String Int-v = evalM e--e' :: Term Sig (Int -> Int)-e' = Term iErr --(iLam id)--v' :: Either String (Int -> Either String Int)-v' = evalM e'
− examples/Examples/Param/Graph.hs
@@ -1,77 +0,0 @@-{-# LANGUAGE TypeOperators, MultiParamTypeClasses, TemplateHaskell,- FlexibleInstances, FlexibleContexts, UndecidableInstances,- OverlappingInstances #-}------------------------------------------------------------------------------------ |--- Module : Examples.Param.Graph--- Copyright : (c) 2011 Patrick Bahr, Tom Hvitved--- License : BSD3--- Maintainer : Tom Hvitved <hvitved@diku.dk>--- Stability : experimental--- Portability : non-portable (GHC Extensions)------ Graph representation. The example is taken from (Fegaras and Sheard,--- Revisiting Catamorphisms over Datatypes with Embedded Functions, '96).--------------------------------------------------------------------------------------module Examples.Param.Graph where--import Data.Comp.Param-import Data.Comp.Param.Derive-import Data.Comp.Param.Show ()-import Data.Comp.Param.Equality ()--data N p a b = N p [b] -- Node-data R a b = R (a -> b) -- Recursion-data S a b = S (a -> b) b -- Sharing--$(derive [makeDifunctor, makeShowD, makeEqD, makeOrdD, smartConstructors]- [''N, ''R, ''S])-$(derive [makeDitraversable] [''N])--type Graph p = Term (N p :+: R :+: S)--class FlatG f p where- flatGAlg :: Alg f [p]--$(derive [liftSum] [''FlatG])--flatG :: (Difunctor f, FlatG f p) => Term f -> [p]-flatG = cata flatGAlg--instance FlatG (N p) p where- flatGAlg (N p ps) = p : concat ps--instance FlatG R p where- flatGAlg (R f) = f []--instance FlatG S p where- flatGAlg (S f g) = f g--class SumG f where- sumGAlg :: Alg f Int--$(derive [liftSum] [''SumG])--sumG :: (Difunctor f, SumG f) => Term f -> Int-sumG = cata sumGAlg--instance SumG (N Int) where- sumGAlg (N p ps) = p + sum ps--instance SumG R where- sumGAlg (R f) = f 0--instance SumG S where- sumGAlg (S f g) = f g--g :: Graph Int-g = Term $ iR (\x -> iS (\z -> iN (0 :: Int) [z,iR $ \y -> iN (1 :: Int) [y,z]])- (iN (2 :: Int) [x]))--f :: [Int]-f = flatG g--n :: Int-n = sumG g
− examples/Examples/Param/Lambda.hs
@@ -1,131 +0,0 @@-{-# LANGUAGE TemplateHaskell, TypeOperators, MultiParamTypeClasses,- FlexibleInstances, FlexibleContexts, UndecidableInstances,- OverlappingInstances, Rank2Types, GADTs #-}------------------------------------------------------------------------------------ |--- Module : Examples.Param.Lambda--- Copyright : (c) 2011 Patrick Bahr, Tom Hvitved--- License : BSD3--- Maintainer : Tom Hvitved <hvitved@diku.dk>--- Stability : experimental--- Portability : non-portable (GHC Extensions)------ Lambda calculus examples------ We define a pretty printer, a desugaring transformation, constant folding,--- and call-by-value interpreter for an extended variant of the simply typed--- lambda calculus.--------------------------------------------------------------------------------------module Examples.Param.Lambda where--import Data.Comp.Param-import Data.Comp.Param.Show ()-import Data.Comp.Param.Equality ()-import Data.Comp.Param.Ordering ()-import Data.Comp.Param.Derive-import Data.Comp.Param.Desugar--data Lam a b = Lam (a -> b)-data App a b = App b b-data Const a b = Const Int-data Plus a b = Plus b b-data Let a b = Let b (a -> b)-data Err a b = Err--type Sig = Lam :+: App :+: Const :+: Plus :+: Let :+: Err-type Sig' = Lam :+: App :+: Const :+: Plus :+: Err--$(derive [smartConstructors, makeDifunctor, makeShowD, makeEqD, makeOrdD]- [''Lam, ''App, ''Const, ''Plus, ''Let, ''Err])---- * Pretty printing-data Stream a = Cons a (Stream a)--class Pretty f where- prettyAlg :: Alg f (Stream String -> String)--$(derive [liftSum] [''Pretty])--pretty :: (Difunctor f, Pretty f) => Term f -> String-pretty t = cata prettyAlg t (nominals 1)- where nominals n = Cons ('x' : show n) (nominals (n + 1))--instance Pretty Lam where- prettyAlg (Lam f) (Cons x xs) = "(\\" ++ x ++ ". " ++ f (const x) xs ++ ")"--instance Pretty App where- prettyAlg (App e1 e2) xs = "(" ++ e1 xs ++ " " ++ e2 xs ++ ")"--instance Pretty Const where- prettyAlg (Const n) _ = show n--instance Pretty Plus where- prettyAlg (Plus e1 e2) xs = "(" ++ e1 xs ++ " + " ++ e2 xs ++ ")"--instance Pretty Err where- prettyAlg Err _ = "error"--instance Pretty Let where- prettyAlg (Let e1 e2) (Cons x xs) = "let " ++ x ++ " = " ++ e1 xs ++ " in " ++ e2 (const x) xs---- * Desugaring-instance (Difunctor f, App :<: f, Lam :<: f) => Desugar Let f where- desugHom' (Let e1 e2) = inject (Lam e2) `iApp` e1---- * Constant folding-class Constf f g where- constfAlg :: forall a. Alg f (Trm g a)--$(derive [liftSum] [''Constf])--constf :: (Difunctor f, Constf f g) => Term f -> Term g-constf t = Term (cata constfAlg t)--instance (Difunctor f, f :<: g) => Constf f g where- constfAlg = inject . dimap Var id -- default instance--instance (Plus :<: f, Const :<: f) => Constf Plus f where- constfAlg (Plus e1 e2) = case (project e1, project e2) of- (Just (Const n),Just (Const m)) -> iConst (n + m)- _ -> e1 `iPlus` e2---- * Call-by-value evaluation-data Sem m = Fun (Sem m -> m (Sem m)) | Int Int--class Monad m => Eval f m where- evalAlg :: Alg f (m (Sem m))--$(derive [liftSum] [''Eval])--eval :: (Difunctor f, Eval f m) => Term f -> m (Sem m)-eval = cata evalAlg--instance Monad m => Eval Lam m where- evalAlg (Lam f) = return (Fun (f . return))--instance Monad m => Eval App m where- evalAlg (App mx my) = do x <- mx- case x of Fun f -> f =<< my; _ -> fail "stuck"--instance Monad m => Eval Const m where- evalAlg (Const n) = return (Int n)--instance Monad m => Eval Plus m where- evalAlg (Plus mx my) = do x <- mx- y <- my- case (x,y) of (Int n,Int m) -> return (Int (n + m))- _ -> fail "stuck"--instance Monad m => Eval Err m where- evalAlg Err = fail "error"--e :: Term Sig-e = Term (iLet (iConst 2) (\x -> (iLam (\y -> y `iPlus` x) `iApp` iConst 3)))--e' :: Term Sig'-e' = desugar e--evalEx :: Maybe (Sem Maybe)-evalEx = eval e'
− examples/Examples/Param/Names.hs
@@ -1,113 +0,0 @@-{-# LANGUAGE TemplateHaskell, TypeOperators, MultiParamTypeClasses,- FlexibleInstances, FlexibleContexts, UndecidableInstances,- OverlappingInstances #-}------------------------------------------------------------------------------------ |--- Module : Examples.Param.Names--- Copyright : (c) 2011 Patrick Bahr, Tom Hvitved--- License : BSD3--- Maintainer : Tom Hvitved <hvitved@diku.dk>--- Stability : experimental--- Portability : non-portable (GHC Extensions)------ From names to parametric higher-order abstract syntax and back------ The example illustrates how to convert a parse tree with explicit names into--- an AST that uses parametric higher-order abstract syntax, and back again. The--- example shows how we can easily convert object language binders to Haskell--- binders, without having to worry about capture avoidance.--------------------------------------------------------------------------------------module Examples.Param.Names where--import Data.Comp.Param hiding (Var)-import qualified Data.Comp.Param as P-import Data.Comp.Param.Derive-import Data.Comp.Param.Ditraversable-import Data.Comp.Param.Show ()-import Data.Maybe-import qualified Data.Map as Map-import Control.Monad.Reader--data Lam a b = Lam (a -> b)-data App a b = App b b-data Lit a b = Lit Int-data Plus a b = Plus b b-type Name = String -- The type of names-data NLam a b = NLam Name b-data NVar a b = NVar Name-type SigB = App :+: Lit :+: Plus-type SigN = NLam :+: NVar :+: SigB -- The name signature-type SigP = Lam :+: SigB -- The PHOAS signature--$(derive [makeDifunctor, makeShowD, makeEqD, smartConstructors]- [''Lam, ''App, ''Lit, ''Plus, ''NLam, ''NVar])-$(derive [makeDitraversable]- [''App, ''Lit, ''Plus, ''NLam, ''NVar])------------------------------------------------------------------------------------- Names to PHOAS translation-----------------------------------------------------------------------------------type M f a = Reader (Map.Map Name (Trm f a))--class N2PTrans f g where- n2pAlg :: Alg f (M g a (Trm g a))----- We make the lifting to sums explicit in order to make the N2PTrans--- work with the default instance declaration further below.-instance (N2PTrans f1 g, N2PTrans f2 g) => N2PTrans (f1 :+: f2) g where- n2pAlg = caseD n2pAlg n2pAlg--n2p :: (Difunctor f, N2PTrans f g) => Term f -> Term g-n2p t = Term $ runReader (cata n2pAlg t) Map.empty--instance (Lam :<: g) => N2PTrans NLam g where- n2pAlg (NLam x b) = do vars <- ask- return $ iLam $ \y -> runReader b (Map.insert x y vars)--instance (Ditraversable f, f :<: g) => N2PTrans f g where- n2pAlg = liftM inject . disequence . dimap (return . P.Var) id -- default--instance N2PTrans NVar g where- n2pAlg (NVar x) = liftM fromJust (asks (Map.lookup x))--en :: Term SigN-en = Term $ iNLam "x1" $ iNLam "x2" (iNLam "x3" $ iNVar "x2") `iApp` iNVar "x1"--ep :: Term SigP-ep = n2p en------------------------------------------------------------------------------------- PHOAS to names translation-----------------------------------------------------------------------------------type M' = Reader [Name]--class P2NTrans f g where- p2nAlg :: Alg f (M' (Trm g a))----- We make the lifting to sums explicit in order to make the P2NTrans--- work with the default instance declaration further below.-instance (P2NTrans f1 g, P2NTrans f2 g) => P2NTrans (f1 :+: f2) g where- p2nAlg = caseD p2nAlg p2nAlg---p2n :: (Difunctor f, P2NTrans f g) => Term f -> Term g-p2n t = Term $ runReader (cata p2nAlg t) ['x' : show n | n <- [1..]]--instance (Ditraversable f, f :<: g) => P2NTrans f g where- p2nAlg = liftM inject . disequence . dimap (return . P.Var) id -- default--instance (NLam :<: g, NVar :<: g) => P2NTrans Lam g where- p2nAlg (Lam f) = do n:names <- ask- return $ iNLam n (runReader (f (return $ iNVar n)) names)--ep' :: Term SigP-ep' = Term $ iLam $ \a -> iLam (\b -> (iLam $ \_ -> b)) `iApp` a--en' :: Term SigN-en' = p2n ep'
+ examples/Examples/Thunk.hs view
@@ -0,0 +1,84 @@+{-# LANGUAGE TemplateHaskell, TypeOperators, MultiParamTypeClasses, DeriveFunctor,+ FlexibleInstances, FlexibleContexts, UndecidableInstances, ConstraintKinds,+ CPP #-}+--------------------------------------------------------------------------------+-- |+-- Module : Examples.Thunk+-- Copyright : (c) 2011 Patrick Bahr, Tom Hvitved+-- License : BSD3+-- Maintainer : Tom Hvitved <hvitved@diku.dk>+-- Stability : experimental+-- Portability : non-portable (GHC Extensions)+--+-- This example illustrates how the ''Data.Comp.Thunk'' package can be+-- used to implement a non-strict language (or a partially non-strict+-- language).+--+--------------------------------------------------------------------------------++module Examples.Thunk where++import Data.Comp+import Data.Comp.Thunk+import Data.Comp.Derive+import Data.Comp.Show()+import Examples.Common hiding (Value(..), Sig, iConst, iPair)++-- Control.Monad.Fail import is redundant since GHC 8.8.1+#if !MIN_VERSION_base(4,13,0)+import Control.Monad.Fail+#endif++-- Signature for values, strict pairs+data Value a = Const Int | Pair !a !a deriving Functor++-- Signature for the simple expression language+type Sig = Op :+: Value++-- Derive boilerplate code using Template Haskell+$(derive [makeTraversable, makeFoldable,+ makeEqF, makeShowF, smartConstructors, makeHaskellStrict]+ [''Value])++-- Monadic term evaluation algebra+class EvalT f m v where+ evalAlgT :: MonadFail m => AlgT m f v++$(derive [liftSum] [''EvalT])++-- Lift the monadic evaluation algebra to a monadic catamorphism+evalT :: (Traversable v, Functor f, EvalT f m v, MonadFail m) => Term f -> m (Term v)+evalT = nf . cata evalAlgT++instance (Value :<: m :+: v) => EvalT Value m v where+-- make pairs strict in both components+-- evalAlgT x@Pair{} = strict x+-- or explicitly:+-- evalAlgT (Pair x y) = thunk $ liftM2 iPair (dethunk' x) (dethunk' )y+-- evalAlgT x = inject x++-- or only partially strict+ evalAlgT = haskellStrict'++instance (Value :<: m :+: v, Value :<: v) => EvalT Op m v where+ evalAlgT (Add x y) = thunk $ do+ Const n1 <- whnfPr x+ Const n2 <- whnfPr y+ return $ iConst $ n1 + n2+ evalAlgT (Mult x y) = thunk $ do+ Const n1 <- whnfPr x+ Const n2 <- whnfPr y+ return $ iConst $ n1 * n2+ evalAlgT (Fst v) = thunk $ do + Pair x _ <- whnfPr v+ return x+ evalAlgT (Snd v) = thunk $ do + Pair _ y <- whnfPr v+ return y+++instance MonadFail (Either String) where+ fail = Left++evalTEx :: Either String (Term Value)+evalTEx = evalT (iSnd (iFst (iConst 5) `iPair` iConst 4) :: Term Sig)
src/Data/Comp.hs view
@@ -18,10 +18,10 @@ module X ) where -import Data.Comp.Term as X import Data.Comp.Algebra as X-import Data.Comp.Sum as X import Data.Comp.Annotation as X import Data.Comp.Equality as X-import Data.Comp.Ordering as X import Data.Comp.Generic as X+import Data.Comp.Ordering as X+import Data.Comp.Sum as X+import Data.Comp.Term as X
src/Data/Comp/Algebra.hs view
@@ -1,5 +1,10 @@-{-# LANGUAGE GADTs, Rank2Types, ScopedTypeVariables, TypeOperators,- FlexibleContexts, CPP #-}+{-# LANGUAGE CPP #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE GADTs #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE Rank2Types #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeOperators #-} -------------------------------------------------------------------------------- -- | -- Module : Data.Comp.Algebra@@ -21,7 +26,7 @@ cata, cata', appCxt,- + -- * Monadic Algebras & Catamorphisms AlgM, algM,@@ -104,12 +109,12 @@ futuM ) where -import Data.Comp.Term+import Control.Monad hiding (mapM, sequence) import Data.Comp.Ops+import Data.Comp.Term import Data.Traversable-import Control.Monad hiding (sequence, mapM) -import Prelude hiding (sequence, mapM)+import Prelude hiding (mapM, sequence) @@ -127,13 +132,13 @@ run (Term t) = f (fmap run t) {-| Construct a catamorphism from the given algebra. -}-cata :: forall f a . (Functor f) => Alg f a -> Term f -> a +cata :: forall f a . (Functor f) => Alg f a -> Term f -> a {-# NOINLINE [1] cata #-} -- cata f = free f undefined -- the above definition is safe since terms do not contain holes -- -- a direct implementation:-cata f = run +cata f = run where run :: Term f -> a run = f . fmap run . unTerm @@ -157,7 +162,7 @@ {-| This type represents a monadic algebra. It is similar to 'Alg' but the return type is monadic. -} -type AlgM m f a = f a -> m a +type AlgM m f a = f a -> m a {-| Convert a monadic algebra into an ordinary algebra with a monadic carrier. -}@@ -175,7 +180,7 @@ run (Term t) = algm =<< mapM run t {-| Construct a monadic catamorphism from the given monadic algebra. -}-cataM :: forall f m a. (Traversable f, Monad m) => AlgM m f a -> Term f -> m a +cataM :: forall f m a. (Traversable f, Monad m) => AlgM m f a -> Term f -> m a {-# NOINLINE [1] cataM #-} -- cataM = cata . algM cataM algm = run@@ -351,7 +356,7 @@ initial term algebra to the given term algebra. -} homMD :: forall f g m . (Traversable f, Functor g, Monad m) => HomMD m f g -> CxtFunM m f g-homMD f = run +homMD f = run where run :: Cxt h f a -> m (Cxt h g a) run (Hole x) = return (Hole x) run (Term t) = liftM appCxt (f (fmap run t))@@ -379,7 +384,7 @@ {-| This function applies a signature function to the given context. -} appSigFunMD :: forall f g m . (Traversable f, Functor g, Monad m) => SigFunMD m f g -> CxtFunM m f g-appSigFunMD f = run +appSigFunMD f = run where run :: Cxt h f a -> m (Cxt h g a) run (Hole x) = return (Hole x) run (Term t) = liftM Term (f (fmap run t))@@ -394,11 +399,6 @@ => HomM m g h -> HomM m f g -> HomM m f h compHomM' f g = appHomM' f <=< g -{-| Compose two monadic term homomorphisms. -}-compHomM_ :: (Functor h, Functor g, Monad m)- => Hom g h -> HomM m f g -> HomM m f h-compHomM_ f g = liftM (appHom f) . g- {-| Compose a monadic algebra with a monadic term homomorphism to get a new monadic algebra. -} compAlgM :: (Traversable g, Monad m) => AlgM m g a -> HomM m f g -> AlgM m f a@@ -449,12 +449,12 @@ -- | Shortcut fusion variant of 'ana'. ana' :: forall a f . Functor f => Coalg f a -> a -> Term f-ana' f t = build $ run t+ana' f t = build (run t) where run :: forall b . a -> Alg f b -> b run t con = run' t where run' :: a -> b run' t = con $ fmap run' (f t)-+{-# INLINE [2] ana' #-} build :: (forall a. Alg f a -> a) -> Term f {-# INLINE [1] build #-} build g = g Term@@ -466,7 +466,7 @@ {-| Construct a monadic anamorphism from the given monadic coalgebra. -} anaM :: forall a m f. (Traversable f, Monad m) => CoalgM m f a -> a -> m (Term f)-anaM f = run +anaM f = run where run :: a -> m (Term f) run t = liftM Term $ f t >>= mapM run @@ -488,7 +488,7 @@ type RAlgM m f a = f (Term f, a) -> m a {-| Construct a monadic paramorphism from the given monadic r-algebra. -}-paraM :: (Traversable f, Monad m) => +paraM :: (Traversable f, Monad m) => RAlgM m f a -> Term f -> m a paraM f = liftM snd . cataM run where run t = do@@ -504,7 +504,7 @@ {-| Construct an apomorphism from the given r-coalgebra. -} apo :: (Functor f) => RCoalg f a -> a -> Term f-apo f = run +apo f = run where run = Term . fmap run' . f run' (Left t) = t run' (Right a) = run a@@ -521,7 +521,7 @@ {-| Construct a monadic apomorphism from the given monadic r-coalgebra. -} apoM :: (Traversable f, Monad m) => RCoalgM m f a -> a -> m (Term f)-apoM f = run +apoM f = run where run a = do t <- f a t' <- mapM run' t@@ -607,6 +607,7 @@ appAlgHom :: forall f g d . (Functor g) => Alg g d -> Hom f g -> Term f -> d+{-# NOINLINE [1] appAlgHom #-} appAlgHom alg hom = run where run :: Term f -> d run (Term t) = run' $ hom t@@ -632,6 +633,7 @@ -- requirements on the source signature @f@. appAlgHomM :: forall m f g a. (Traversable g, Monad m) => AlgM m g a -> HomM m f g -> Term f -> m a+{-# NOINLINE [1] appAlgHomM #-} appAlgHomM alg hom = run where run :: Term f -> m a run (Term t) = hom t >>= mapM run >>= run'@@ -712,7 +714,7 @@ "appHom/appHom'" forall (a :: Hom g h) (h :: Hom f g) x. appHom a (appHom' h x) = appHom' (compHom a h) x;- + "appSigFun/appSigFun" forall (f :: SigFun g h) (g :: SigFun f g) x. appSigFun f (appSigFun g x) = appSigFun (compSigFun f g) x; @@ -736,7 +738,7 @@ "appHom'/appSigFun" forall (f :: Hom g h) (g :: SigFun f g) x. appHom' f (appSigFun g x) = appHom (compHomSigFun f g) x;- + "appSigFun/appHom" forall (f :: SigFun g h) (g :: Hom f g) x. appSigFun f (appHom g x) = appSigFunHom f g x; @@ -748,7 +750,7 @@ "appSigFun'/appHom" forall (f :: SigFun g h) (g :: Hom f g) x. appSigFun' f (appHom g x) = appHom (compSigFunHom f g) x;- + "appSigFunHom/appSigFun" forall (f :: SigFun f3 f4) (g :: Hom f2 f3) (h :: SigFun f1 f2) x. appSigFunHom f g (appSigFun h x)@@ -788,10 +790,9 @@ "appSigFunHom/appSigFunHom" forall (f1 :: SigFun f4 f5) (f2 :: Hom f3 f4) (f3 :: SigFun f2 f3) (f4 :: Hom f1 f2) x. appSigFunHom f1 f2 (appSigFunHom f3 f4 x)- = appSigFunHom f1 (compHom (compHomSigFun f2 f3) f4) x;- #-}+ = appSigFunHom f1 (compHom (compHomSigFun f2 f3) f4) x; #-} -{-# RULES +{-# RULES "cataM/appHomM" forall (a :: AlgM Maybe g d) (h :: HomM Maybe f g) x. appHomM h x >>= cataM a = appAlgHomM a h x; @@ -917,14 +918,9 @@ "appSigFunM'/appSigFun'" forall (a :: SigFunM m g h) (h :: SigFun f g) x. appSigFunM' a (appSigFun' h x) = appSigFunM' (compSigFunM a (sigFunM h)) x;--- "appHom/appHomM" forall (a :: Hom g h) (h :: HomM m f g) x.- appHomM h x >>= (return . appHom a) = appHomM (compHomM_ a h) x;- #-}+#-} {-# RULES "cata/build" forall alg (g :: forall a . Alg f a -> a) .- cata alg (build g) = g alg- #-}+ cata alg (build g) = g alg #-} #endif
src/Data/Comp/Annotation.hs view
@@ -1,9 +1,16 @@-{-# LANGUAGE TypeOperators, MultiParamTypeClasses, FlexibleInstances,- UndecidableInstances, Rank2Types, GADTs, ScopedTypeVariables, FlexibleContexts #-}+{-# LANGUAGE ConstraintKinds #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE GADTs #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE Rank2Types #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeOperators #-}+{-# LANGUAGE UndecidableInstances #-} -------------------------------------------------------------------------------- -- | -- Module : Data.Comp.Annotation--- Copyright : (c) 2010-2011 Patrick Bahr+-- Copyright : (c) 2010-2013 Patrick Bahr -- License : BSD3 -- Maintainer : Patrick Bahr <paba@diku.dk> -- Stability : experimental@@ -23,21 +30,17 @@ liftA', stripA, propAnn,- propAnnQ,- propAnnUp,- propAnnDown, propAnnM, ann, project' ) where -import Data.Comp.Term-import Data.Comp.Sum-import Data.Comp.Ops-import Data.Comp.Algebra-import Data.Comp.Automata import Control.Monad+import Data.Comp.Algebra+import Data.Comp.Ops+import Data.Comp.Term + {-| Transform a function with a domain constructed from a functor to a function with a domain constructed with the same functor, but with an additional annotation. -}@@ -51,47 +54,22 @@ => (s' a -> Cxt h s' a) -> s a -> Cxt h s a liftA' f v = let (v',p) = projectA v in ann p (f v')- + {-| Strip the annotations from a term over a functor with annotations. -} stripA :: (RemA g f, Functor g) => CxtFun g f stripA = appSigFun remA {-| Lift a term homomorphism over signatures @f@ and @g@ to a term homomorphism over the same signatures, but extended with annotations. -}-propAnn :: (DistAnn f p f', DistAnn g p g', Functor g) +propAnn :: (DistAnn f p f', DistAnn g p g', Functor g) => Hom f g -> Hom f' g' propAnn hom f' = ann p (hom f) where (f,p) = projectA f' --- | Lift a stateful term homomorphism over signatures @f@ and @g@ to--- a stateful term homomorphism over the same signatures, but extended with--- annotations.-propAnnQ :: (DistAnn f p f', DistAnn g p g', Functor g) - => QHom f q g -> QHom f' q g'-propAnnQ hom f' = ann p (hom f)- where (f,p) = projectA f'---- | Lift a bottom-up tree transducer over signatures @f@ and @g@ to a--- bottom-up tree transducer over the same signatures, but extended--- with annotations.-propAnnUp :: (DistAnn f p f', DistAnn g p g', Functor g) - => UpTrans f q g -> UpTrans f' q g'-propAnnUp trans f' = (q, ann p t)- where (f,p) = projectA f'- (q,t) = trans f---- | Lift a top-down tree transducer over signatures @f@ and @g@ to a--- top-down tree transducer over the same signatures, but extended--- with annotations.-propAnnDown :: (DistAnn f p f', DistAnn g p g', Functor g) - => DownTrans f q g -> DownTrans f' q g'-propAnnDown trans (q, f') = ann p (trans (q, f))- where (f,p) = projectA f'- {-| Lift a monadic term homomorphism over signatures @f@ and @g@ to a monadic term homomorphism over the same signatures, but extended with annotations. -}-propAnnM :: (DistAnn f p f', DistAnn g p g', Functor g, Monad m) +propAnnM :: (DistAnn f p f', DistAnn g p g', Functor g, Monad m) => HomM m f g -> HomM m f' g' propAnnM hom f' = liftM (ann p) (hom f) where (f,p) = projectA f'@@ -100,9 +78,9 @@ ann :: (DistAnn f p g, Functor f) => p -> CxtFun f g ann c = appSigFun (injectA c) + {-| This function is similar to 'project' but applies to signatures with an annotation which is then ignored. -}--- bug in type checker? below is the inferred type, however, the type checker--- rejects it.-project' :: forall f g f1 a h . (RemA f g, f :<: f1) => Cxt h f1 a -> Maybe (g (Cxt h f1 a))-project' v = liftM remA (project v :: Maybe (f (Cxt h f1 a)))+project' :: (RemA f f', s :<: f') => Cxt h f a -> Maybe (s (Cxt h f a))+project' (Term x) = proj $ remA x+project' _ = Nothing
src/Data/Comp/Arbitrary.hs view
@@ -1,4 +1,8 @@-{-# LANGUAGE TypeOperators, TypeSynonymInstances, GADTs, TemplateHaskell, FlexibleInstances #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE GADTs #-}+{-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE TypeOperators #-}+{-# LANGUAGE TypeSynonymInstances #-} -------------------------------------------------------------------------------- -- | -- Module : Data.Comp.Arbitrary@@ -17,13 +21,11 @@ ( ArbitraryF(..) )where -import Test.QuickCheck-import Data.Comp.Term-import Data.Comp.Sum-import Data.Comp.Ops-import Data.Comp.Derive.Utils import Data.Comp.Derive-import Control.Applicative+import Data.Comp.Derive.Utils+import Data.Comp.Ops+import Data.Comp.Term+import Test.QuickCheck {-| This lifts instances of 'ArbitraryF' to instances of 'Arbitrary' for the corresponding term type. -}@@ -36,10 +38,10 @@ arbitraryF' = map addP arbitraryF' where addP (i,gen) = (i,(:&:) <$> gen <*> arbitrary) arbitraryF = (:&:) <$> arbitraryF <*> arbitrary- shrinkF (v :&: p) = tail [v' :&: p'| v' <- v: shrinkF v, p' <- p : shrink p ]+ shrinkF (v :&: p) = drop 1 [v' :&: p'| v' <- v: shrinkF v, p' <- p : shrink p ] {-|- This lifts instances of 'ArbitraryF' to instances of 'ArbitraryF' for + This lifts instances of 'ArbitraryF' to instances of 'ArbitraryF' for the corresponding context functor. -} instance (ArbitraryF f) => ArbitraryF (Context f) where
− src/Data/Comp/Automata.hs
@@ -1,483 +0,0 @@-{-# LANGUAGE Rank2Types, FlexibleContexts, ImplicitParams, GADTs, TypeOperators #-}------------------------------------------------------------------------------------- |--- Module : Data.Comp.Automata--- Copyright : (c) 2010-2012 Patrick Bahr--- License : BSD3--- Maintainer : Patrick Bahr <paba@diku.dk>--- Stability : experimental--- Portability : non-portable (GHC Extensions)------ This module defines stateful term homomorphisms. This (slightly--- oxymoronic) notion extends per se stateless term homomorphisms with--- a state that is maintained separately by a bottom-up or top-down--- state transformation. Additionally, this module also provides--- combinators to run state transformations themselves.--- --- Like regular term homomorphisms also stateful homomorphisms (as--- well as transducers) can be lifted to annotated signatures--- (cf. "Data.Comp.Annotation").------ The recursion schemes provided in this module are derived from tree--- automata. They allow for a higher degree of modularity and make it--- possible to apply fusion. The implementation is based on the paper--- /Modular Tree Automata/ (Mathematics of Program Construction,--- 263-299, 2012, <http://dx.doi.org/10.1007/978-3-642-31113-0_14>).--------------------------------------------------------------------------------------module Data.Comp.Automata- (- -- * Stateful Term Homomorphisms- QHom- , below- , above- , pureHom- -- ** Bottom-Up State Propagation- , upTrans- , runUpHom- , runUpHomSt- -- ** Top-Down State Propagation- , downTrans- , runDownHom- -- ** Bidirectional State Propagation- , runQHom- -- * Deterministic Bottom-Up Tree Transducers- , UpTrans- , runUpTrans- , compUpTrans- , compUpTransHom- , compHomUpTrans- , compUpTransSig- , compSigUpTrans- , compAlgUpTrans- -- * Deterministic Bottom-Up Tree State Transformations- -- ** Monolithic State- , UpState- , tagUpState- , runUpState- , prodUpState- -- ** Modular State- , DUpState- , dUpState- , upState- , runDUpState- , prodDUpState- , (<*>)- -- * Deterministic Top-Down Tree Transducers- , DownTrans- , runDownTrans- , compDownTrans- , compDownTransSig- , compSigDownTrans- , compDownTransHom- , compHomDownTrans- -- * Deterministic Top-Down Tree State Transformations- -- ** Monolithic State- , DownState- , tagDownState- , prodDownState- -- ** Modular State- , DDownState- , dDownState- , downState- , prodDDownState- , (>*<)- -- * Bidirectional Tree State Transformations- , runDState- -- * Operators for Finite Mappings- , (&)- , (|->)- , o- -- * Product State Spaces- , module Data.Comp.Automata.Product- ) where--import Data.Comp.Number-import Data.Comp.Automata.Product-import Data.Comp.Term-import Data.Comp.Algebra-import Data.Map (Map)-import qualified Data.Map as Map------ The following are operators to specify finite mappings.---infix 1 |->-infixr 0 &---- | left-biased union of two mappings.--(&) :: Ord k => Map k v -> Map k v -> Map k v-(&) = Map.union---- | This operator constructs a singleton mapping.--(|->) :: k -> a -> Map k a-(|->) = Map.singleton---- | This is the empty mapping.--o :: Map k a-o = Map.empty---- | This function provides access to components of the states from--- "below".--below :: (?below :: a -> q, p :< q) => a -> p-below = pr . ?below---- | This function provides access to components of the state from--- "above"--above :: (?above :: q, p :< q) => p-above = pr ?above---- | Turns the explicit parameters @?above@ and @?below@ into explicit--- ones.--explicit :: ((?above :: q, ?below :: a -> q) => b) -> q -> (a -> q) -> b-explicit x ab be = x where ?above = ab; ?below = be----- | This type represents stateful term homomorphisms. Stateful term--- homomorphisms have access to a state that is provided (separately)--- by a bottom-up or top-down state transformation function (or both).- -type QHom f q g = forall a . (?below :: a -> q, ?above :: q) => f a -> Context g a----- | This function turns a stateful homomorphism with a fully--- polymorphic state type into a (stateless) homomorphism.-pureHom :: (forall q . QHom f q g) -> Hom f g-pureHom phom t = let ?above = undefined - ?below = const undefined- in phom t---- | This type represents transition functions of deterministic--- bottom-up tree transducers (DUTTs).--type UpTrans f q g = forall a. f (q,a) -> (q, Context g a)---- | This function transforms a DUTT transition function into an--- algebra.--upAlg :: (Functor g) => UpTrans f q g -> Alg f (q, Term g)-upAlg trans = fmap appCxt . trans ---- | This function runs the given DUTT on the given term.--runUpTrans :: (Functor f, Functor g) => UpTrans f q g -> Term f -> Term g-runUpTrans trans = snd . runUpTransSt trans---- | This function is a variant of 'runUpTrans' that additionally--- returns the final state of the run.--runUpTransSt :: (Functor f, Functor g) => UpTrans f q g -> Term f -> (q, Term g)-runUpTransSt = cata . upAlg---- | This function generalises 'runUpTrans' to contexts. Therefore,--- additionally, a transition function for the holes is needed.--runUpTrans' :: (Functor f, Functor g) => UpTrans f q g -> Context f (q,a) -> (q, Context g a)-runUpTrans' trans = run where- run (Hole (q,a)) = (q, Hole a)- run (Term t) = fmap appCxt $ trans $ fmap run t---- | This function composes two DUTTs. (see TATA, Theorem 6.4.5)- -compUpTrans :: (Functor f, Functor g, Functor h)- => UpTrans g p h -> UpTrans f q g -> UpTrans f (q,p) h-compUpTrans t2 t1 x = ((q1,q2), c2) where- (q1, c1) = t1 $ fmap (\((q1,q2),a) -> (q1,(q2,a))) x- (q2, c2) = runUpTrans' t2 c1----- | This function composes a DUTT with an algebra.- -compAlgUpTrans :: (Functor g)- => Alg g a -> UpTrans f q g -> Alg f (q,a)-compAlgUpTrans alg trans = fmap (cata' alg) . trans----- | This combinator composes a DUTT followed by a signature function.--compSigUpTrans :: (Functor g) => SigFun g h -> UpTrans f q g -> UpTrans f q h-compSigUpTrans sig trans x = (q, appSigFun sig x') where- (q, x') = trans x---- | This combinator composes a signature function followed by a DUTT.- -compUpTransSig :: UpTrans g q h -> SigFun f g -> UpTrans f q h-compUpTransSig trans sig = trans . sig---- | This combinator composes a DUTT followed by a homomorphism.--compHomUpTrans :: (Functor g, Functor h) => Hom g h -> UpTrans f q g -> UpTrans f q h-compHomUpTrans hom trans x = (q, appHom hom x') where- (q, x') = trans x---- | This combinator composes a homomorphism followed by a DUTT.- -compUpTransHom :: (Functor g, Functor h) => UpTrans g q h -> Hom f g -> UpTrans f q h-compUpTransHom trans hom x = runUpTrans' trans . hom $ x---- | This type represents transition functions of deterministic--- bottom-up tree acceptors (DUTAs).--type UpState f q = Alg f q---- | Changes the state space of the DUTA using the given isomorphism.--tagUpState :: (Functor f) => (q -> p) -> (p -> q) -> UpState f q -> UpState f p-tagUpState i o s = i . s . fmap o---- | This combinator runs the given DUTA on a term returning the final--- state of the run.--runUpState :: (Functor f) => UpState f q -> Term f -> q-runUpState = cata---- | This function combines the product DUTA of the two given DUTAs.--prodUpState :: Functor f => UpState f p -> UpState f q -> UpState f (p,q)-prodUpState sp sq t = (p,q) where- p = sp $ fmap fst t- q = sq $ fmap snd t----- | This function constructs a DUTT from a given stateful term--- homomorphism with the state propagated by the given DUTA.- -upTrans :: (Functor f, Functor g) => UpState f q -> QHom f q g -> UpTrans f q g-upTrans st f t = (q, c)- where q = st $ fmap fst t- c = fmap snd $ explicit f q fst t---- | This function applies a given stateful term homomorphism with--- a state space propagated by the given DUTA to a term.- -runUpHom :: (Functor f, Functor g) => UpState f q -> QHom f q g -> Term f -> Term g-runUpHom st hom = snd . runUpHomSt st hom---- | This is a variant of 'runUpHom' that also returns the final state--- of the run.--runUpHomSt :: (Functor f, Functor g) => UpState f q -> QHom f q g -> Term f -> (q,Term g)-runUpHomSt alg h = runUpTransSt (upTrans alg h)----- | This type represents transition functions of generalised--- deterministic bottom-up tree acceptors (GDUTAs) which have access--- to an extended state space.--type DUpState f p q = forall a . (?below :: a -> p, ?above :: p, q :< p) => f a -> q---- | This combinator turns an arbitrary DUTA into a GDUTA.--dUpState :: Functor f => UpState f q -> DUpState f p q-dUpState f = f . fmap below---- | This combinator turns a GDUTA with the smallest possible state--- space into a DUTA.--upState :: DUpState f q q -> UpState f q-upState f s = res where res = explicit f res id s---- | This combinator runs a GDUTA on a term.- -runDUpState :: Functor f => DUpState f q q -> Term f -> q-runDUpState = runUpState . upState---- | This combinator constructs the product of two GDUTA.--prodDUpState :: (p :< c, q :< c)- => DUpState f c p -> DUpState f c q -> DUpState f c (p,q)-prodDUpState sp sq t = (sp t, sq t)--(<*>) :: (p :< c, q :< c)- => DUpState f c p -> DUpState f c q -> DUpState f c (p,q)-(<*>) = prodDUpState------ | This type represents transition functions of deterministic--- top-down tree transducers (DDTTs).--type DownTrans f q g = forall a. (q, f a) -> Context g (q,a)---- | Thsis function runs the given DDTT on the given tree.--runDownTrans :: (Functor f, Functor g) => DownTrans f q g -> q -> Cxt h f a -> Cxt h g a-runDownTrans tr q t = run (q,t) where- run (q,Term t) = appCxt $ fmap run $ tr (q, t)- run (_,Hole a) = Hole a---- | This function runs the given DDTT on the given tree.- -runDownTrans' :: (Functor f, Functor g) => DownTrans f q g -> q -> Cxt h f a -> Cxt h g (q,a)-runDownTrans' tr q t = run (q,t) where- run (q,Term t) = appCxt $ fmap run $ tr (q, t)- run (q,Hole a) = Hole (q,a)---- | This function composes two DDTTs. (see Z. Fulop, H. Vogler--- /Syntax-Directed Semantics/, Theorem 3.39)- -compDownTrans :: (Functor f, Functor g, Functor h)- => DownTrans g p h -> DownTrans f q g -> DownTrans f (q,p) h-compDownTrans t2 t1 ((q,p), t) = fmap (\(p, (q, a)) -> ((q,p),a)) $ runDownTrans' t2 p (t1 (q, t))----- | This function composes a signature function after a DDTT.--compSigDownTrans :: (Functor g) => SigFun g h -> DownTrans f q g -> DownTrans f q h-compSigDownTrans sig trans = appSigFun sig . trans---- | This function composes a DDTT after a function.--compDownTransSig :: DownTrans g q h -> SigFun f g -> DownTrans f q h-compDownTransSig trans hom (q,t) = trans (q, hom t)----- | This function composes a homomorphism after a DDTT.--compHomDownTrans :: (Functor g, Functor h)- => Hom g h -> DownTrans f q g -> DownTrans f q h-compHomDownTrans hom trans = appHom hom . trans---- | This function composes a DDTT after a homomorphism.--compDownTransHom :: (Functor g, Functor h)- => DownTrans g q h -> Hom f g -> DownTrans f q h-compDownTransHom trans hom (q,t) = runDownTrans' trans q (hom t)----- | This type represents transition functions of deterministic--- top-down tree acceptors (DDTAs).--type DownState f q = forall a. Ord a => (q, f a) -> Map a q----- | Changes the state space of the DDTA using the given isomorphism.--tagDownState :: (q -> p) -> (p -> q) -> DownState f q -> DownState f p-tagDownState i o t (q,s) = fmap i $ t (o q,s)---- | This function constructs the product DDTA of the given two DDTAs.--prodDownState :: DownState f p -> DownState f q -> DownState f (p,q)-prodDownState sp sq ((p,q),t) = prodMap p q (sp (p, t)) (sq (q, t))----- | This type is needed to construct the product of two DDTAs.--data ProdState p q = LState p- | RState q- | BState p q--- | This function constructs the pointwise product of two maps each--- with a default value.--prodMap :: (Ord i) => p -> q -> Map i p -> Map i q -> Map i (p,q)-prodMap p q mp mq = Map.map final $ Map.unionWith combine ps qs- where ps = Map.map LState mp- qs = Map.map RState mq- combine (LState p) (RState q) = BState p q- combine (RState q) (LState p) = BState p q- combine _ _ = error "unexpected merging"- final (LState p) = (p, q)- final (RState q) = (p, q)- final (BState p q) = (p,q)----- | Apply the given state mapping to the given functorial value by--- adding the state to the corresponding index if it is in the map and--- otherwise adding the provided default state.- -appMap :: Traversable f => (forall i . Ord i => f i -> Map i q)- -> q -> f b -> f (q,b)-appMap qmap q s = fmap qfun s'- where s' = number s- qfun k@(Numbered (_,a)) = (Map.findWithDefault q k (qmap s') ,a)---- | This function constructs a DDTT from a given stateful term----- homomorphism with the state propagated by the given DDTA.- -downTrans :: Traversable f => DownState f q -> QHom f q g -> DownTrans f q g-downTrans st f (q, s) = explicit f q fst (appMap (curry st q) q s)----- | This function applies a given stateful term homomorphism with a--- state space propagated by the given DDTA to a term.--runDownHom :: (Traversable f, Functor g)- => DownState f q -> QHom f q g -> q -> Term f -> Term g-runDownHom st h = runDownTrans (downTrans st h)---- | This type represents transition functions of generalised--- deterministic top-down tree acceptors (GDDTAs) which have access---- to an extended state space.-type DDownState f p q = forall i . (Ord i, ?below :: i -> p, ?above :: p, q :< p)- => f i -> Map i q---- | This combinator turns an arbitrary DDTA into a GDDTA.--dDownState :: DownState f q -> DDownState f p q-dDownState f t = f (above,t)---- | This combinator turns a GDDTA with the smallest possible state--- space into a DDTA.--downState :: DDownState f q q -> DownState f q-downState f (q,s) = res- where res = explicit f q bel s- bel k = Map.findWithDefault q k res----- | This combinator constructs the product of two dependant top-down--- state transformations.- -prodDDownState :: (p :< c, q :< c)- => DDownState f c p -> DDownState f c q -> DDownState f c (p,q)-prodDDownState sp sq t = prodMap above above (sp t) (sq t)---- | This is a synonym for 'prodDDownState'.--(>*<) :: (p :< c, q :< c, Functor f)- => DDownState f c p -> DDownState f c q -> DDownState f c (p,q)-(>*<) = prodDDownState----- | This combinator combines a bottom-up and a top-down state--- transformations. Both state transformations can depend mutually--- recursive on each other.--runDState :: Traversable f => DUpState f (u,d) u -> DDownState f (u,d) d -> d -> Term f -> u-runDState up down d (Term t) = u where- t' = fmap bel $ number t- bel (Numbered (i,s)) = - let d' = Map.findWithDefault d (Numbered (i,undefined)) m- in Numbered (i, (runDState up down d' s, d'))- m = explicit down (u,d) unNumbered t'- u = explicit up (u,d) unNumbered t'---- | This combinator runs a stateful term homomorphisms with a state--- space produced both on a bottom-up and a top-down state--- transformation.- -runQHom :: (Traversable f, Functor g) =>- DUpState f (u,d) u -> DDownState f (u,d) d -> - QHom f (u,d) g ->- d -> Term f -> (u, Term g)-runQHom up down trans d (Term t) = (u,t'') where- t' = fmap bel $ number t- bel (Numbered (i,s)) = - let d' = Map.findWithDefault d (Numbered (i,undefined)) m- (u', s') = runQHom up down trans d' s- in Numbered (i, ((u', d'),s'))- m = explicit down (u,d) (fst . unNumbered) t'- u = explicit up (u,d) (fst . unNumbered) t'- t'' = appCxt $ fmap (snd . unNumbered) $ explicit trans (u,d) (fst . unNumbered) t'
− src/Data/Comp/Automata/Product.hs
@@ -1,25 +0,0 @@-{-# LANGUAGE TypeOperators, MultiParamTypeClasses, FlexibleInstances, IncoherentInstances, TemplateHaskell #-}------------------------------------------------------------------------------------ |--- Module : Data.Comp.Automata.Product--- Copyright : (c) 2011 Patrick Bahr--- License : BSD3--- Maintainer : Patrick Bahr <paba@diku.dk>--- Stability : experimental--- Portability : non-portable (GHC Extensions)-----------------------------------------------------------------------------------------module Data.Comp.Automata.Product ((:<)(..)) where--import Data.Comp.Automata.Product.Derive---instance a :< a where- pr = id--$(genAllInsts 7)--instance (c :< b) => c :< (a,b) where- pr = pr . snd
− src/Data/Comp/Automata/Product/Derive.hs
@@ -1,73 +0,0 @@-{-# LANGUAGE TypeOperators, MultiParamTypeClasses, FlexibleInstances, IncoherentInstances #-}------------------------------------------------------------------------------------ |--- Module : Data.Comp.Automata.Product.Derive--- Copyright : (c) 2011 Patrick Bahr--- License : BSD3--- Maintainer : Patrick Bahr <paba@diku.dk>--- Stability : experimental--- Portability : non-portable (GHC Extensions)-----------------------------------------------------------------------------------------module Data.Comp.Automata.Product.Derive where--import Language.Haskell.TH---- | An instance @a :< b@ means that @a@ is a component of @b@. @a@--- can be extracted from @b@ via the method 'pr'.-class a :< b where- pr :: b -> a--data Dir = L | R- deriving Show--genAllInsts :: Int -> Q [Dec]-genAllInsts n = mapM genInst dirs- where dirs = map (L:) (genDirs n)--genDirs :: Int -> [[Dir]]-genDirs 0 = [[]]-genDirs n = [] : map (L:) dirs ++ map (R:) dirs- where dirs = genDirs (n-1)--genInst :: [Dir] -> Q Dec-genInst dir = do - n <- newName "a"- ty <- genType n dir- ex <- genEx dir- return $ InstanceD [] (ConT (mkName ":<") `AppT` VarT n `AppT` ty) [ex]--genType :: Name -> [Dir] -> Q Type-genType n = gen- where gen [] = varT n- gen (L:dir) = gen dir `pairT` (varT =<< newName "a")- gen (R:dir) = (varT =<< newName "a") `pairT` gen dir --genPat :: Name -> [Dir] -> PatQ-genPat n = gen where- gen [] = varP n- gen (L:dir) = tupP [gen dir,wildP]- gen (R:dir) = tupP [wildP,gen dir]--genEx :: [Dir] -> DecQ-genEx dir = do- n <- newName "x"- p <- genPat n dir- return $ FunD (mkName "pr") [Clause [p] (NormalB (VarE n)) []]--genPatExp :: Name -> [Dir] -> Q (Pat, Exp)-genPatExp n = gen where- gen [] = return (WildP, VarE n)- gen (d:dir) = do - (p,e) <- gen dir - x <- newName "x"- return $ case d of- L -> (TupP [p,VarP x] , TupE [e,VarE x])- R -> (TupP [VarP x,p] , TupE [VarE x,e])- ---pairT :: TypeQ -> TypeQ -> TypeQ-pairT x = appT (appT (tupleT 2) x)
src/Data/Comp/Decompose.hs view
@@ -1,4 +1,7 @@-{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances, UndecidableInstances #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE UndecidableInstances #-}+{-# LANGUAGE ConstraintKinds #-} -------------------------------------------------------------------------------- -- |@@ -16,7 +19,8 @@ module Data.Comp.Decompose ( Decomp (..), DecompTerm,- Decompose (..),+ Decompose,+ decomp, structure, arguments, decompose@@ -47,20 +51,17 @@ {-| This class specifies the decomposability of a functorial value. -} -class (HasVars f v, Functor f, Foldable f) => Decompose f v where- {-| This function decomposes a functorial value. -}-- decomp :: f a -> Decomp f v a- decomp t = case isVar t of- Just v -> Var v- Nothing -> Fun sym args- where sym = fmap (const ()) t- args = arguments t+type Decompose f v = (HasVars f v, Functor f, Foldable f) -instance (HasVars f v, Functor f, Foldable f) => Decompose f v where+decomp :: Decompose f v => f a -> Decomp f v a+decomp t = case isVar t of+ Just v -> Var v+ Nothing -> Fun sym args+ where sym = fmap (const ()) t+ args = arguments t {-| This function decomposes a term. -} -decompose :: (Decompose f v) => Term f -> DecompTerm f v+decompose :: Decompose f v => Term f -> DecompTerm f v decompose (Term t) = decomp t
src/Data/Comp/DeepSeq.hs view
@@ -1,5 +1,8 @@-{-# LANGUAGE GADTs, FlexibleContexts, FlexibleInstances, TypeOperators,- TemplateHaskell #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE GADTs #-}+{-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE TypeOperators #-} -------------------------------------------------------------------------------- -- | -- Module : Data.Comp.DeepSeq@@ -16,24 +19,23 @@ module Data.Comp.DeepSeq (- NFDataF(..),- rnfF'+ NFDataF(..) ) where -import Data.Comp.Term import Control.DeepSeq+import Data.Comp.Annotation import Data.Comp.Derive-import Data.Foldable-import Prelude hiding (foldr)+import Data.Comp.Term -{-| Fully evaluate a value over a foldable signature. -}-rnfF' :: (Foldable f, NFDataF f, NFData a) => f a -> ()-rnfF' x = foldr seq (rnfF x) x instance (NFDataF f, NFData a) => NFData (Cxt h f a) where rnf (Hole x) = rnf x rnf (Term x) = rnfF x++instance (NFDataF f, NFData a) => NFDataF (f :&: a) where+ rnfF (f :&: a) = rnfF f `seq` rnf a+ $(derive [liftSum] [''NFDataF]) $(derive [makeNFDataF] [''Maybe, ''[], ''(,)])
src/Data/Comp/Derive.hs view
@@ -25,9 +25,6 @@ module Data.Comp.Derive.Equality, -- ** OrdF module Data.Comp.Derive.Ordering,- -- ** Functor- Functor,- makeFunctor, -- ** Foldable module Data.Comp.Derive.Foldable, -- ** Traversable@@ -37,7 +34,6 @@ -- ** Arbitrary module Data.Comp.Derive.Arbitrary, NFData(..),- makeNFData, -- ** DeepSeq module Data.Comp.Derive.DeepSeq, -- ** Smart Constructors@@ -48,33 +44,24 @@ liftSum ) where -import Control.DeepSeq (NFData(..))-import Data.Comp.Derive.Utils (derive, liftSumGen)-import Data.Comp.Derive.HaskellStrict-import Data.Comp.Derive.Foldable-import Data.Comp.Derive.Traversable+import Control.DeepSeq (NFData (..))+import Data.Comp.Derive.Arbitrary import Data.Comp.Derive.DeepSeq-import Data.Comp.Derive.Show-import Data.Comp.Derive.Ordering import Data.Comp.Derive.Equality-import Data.Comp.Derive.Arbitrary-import Data.Comp.Derive.SmartConstructors+import Data.Comp.Derive.Foldable+import Data.Comp.Derive.HaskellStrict+import Data.Comp.Derive.Ordering+import Data.Comp.Derive.Show import Data.Comp.Derive.SmartAConstructors+import Data.Comp.Derive.SmartConstructors+import Data.Comp.Derive.Traversable+import Data.Comp.Derive.Utils (derive, liftSumGen) import Data.Comp.Ops ((:+:), caseF) import Language.Haskell.TH -import qualified Data.DeriveTH as D-import qualified Data.Derive.All as A -{-| Derive an instance of 'Functor' for a type constructor of any first-order- kind taking at least one argument. -}-makeFunctor :: Name -> Q [Dec]-makeFunctor = D.derive A.makeFunctor -{-| Derive an instance of 'NFData' for a type constructor. -}-makeNFData :: Name -> Q [Dec]-makeNFData = D.derive A.makeNFData {-| Given the name of a type class, where the first parameter is a functor, lift it to sums of functors. Example: @class ShowF f where ...@ is lifted
src/Data/Comp/Derive/Arbitrary.hs view
@@ -1,4 +1,5 @@-{-# LANGUAGE GADTs, TemplateHaskell #-}+{-# LANGUAGE GADTs #-}+{-# LANGUAGE TemplateHaskell #-} -------------------------------------------------------------------------------- -- | -- Module : Data.Comp.Derive.Arbitrary@@ -16,18 +17,12 @@ ( ArbitraryF(..), makeArbitraryF,- Arbitrary(..),- makeArbitrary+ Arbitrary(..) )where -import Test.QuickCheck import Data.Comp.Derive.Utils hiding (derive) import Language.Haskell.TH-import qualified Data.DeriveTH as D--{-| Derive an instance of 'Arbitrary' for a type constructor. -}-makeArbitrary :: Name -> Q [Dec]-makeArbitrary = D.derive D.makeArbitrary+import Test.QuickCheck {-| Signature arbitration. An instance @ArbitraryF f@ gives rise to an instance @Arbitrary (Term f)@. -}@@ -45,14 +40,14 @@ instances of 'Arbitrary'. -} makeArbitraryF :: Name -> Q [Dec] makeArbitraryF dt = do- TyConI (DataD _cxt name args constrs _deriving) <- abstractNewtypeQ $ reify dt+ Just (DataInfo _cxt name args constrs _deriving) <- abstractNewtypeQ $ reify dt let argNames = map (VarT . tyVarBndrName) (tail args) complType = foldl AppT (ConT name) argNames- preCond = map (ClassP ''Arbitrary . (: [])) argNames+ preCond = map (mkClassP ''Arbitrary . (: [])) argNames classType = AppT (ConT ''ArbitraryF) complType arbitraryDecl <- generateArbitraryFDecl constrs shrinkDecl <- generateShrinkFDecl constrs- return [InstanceD preCond classType [arbitraryDecl, shrinkDecl]]+ return [mkInstanceD preCond classType [arbitraryDecl, shrinkDecl]] {-| This function generates a declaration of the method 'arbitrary' for the given@@ -64,7 +59,7 @@ {-| This function generates a declaration of a generator having the given name using the given constructors, i.e., something like this:- + @ \<name\> :: Gen \<type\> \<name\> = ...@@ -96,10 +91,10 @@ let build = doE $ binds ++ [noBindS [|return $apps|]]- if n == 0 + if n == 0 then [|return $apps|] else [| sized $ \ size ->- $(letE [valD + $(letE [valD newSizeP (normalB [|((size - 1) `div` $constrsE ) `max` 0|]) [] ]@@ -119,5 +114,5 @@ binds <- mapM (\(var,resVar) -> bindS (varP resVar) [| $(varE var) : shrink $(varE var) |]) $ zip varNs resVarNs let ret = NoBindS $ AppE (VarE 'return) (foldl1 AppE ( ConE constr: map VarE resVarNs )) stmtSeq = binds ++ [ret]- pat = ConP constr $ map VarP varNs- return $ Clause [pat] (NormalB $ AppE (VarE 'tail) (DoE stmtSeq)) []+ pat = ConP constr [] $ map VarP varNs+ return $ Clause [pat] (NormalB $ AppE (VarE 'tail) (DoE Nothing stmtSeq)) []
src/Data/Comp/Derive/DeepSeq.hs view
@@ -22,7 +22,6 @@ import Control.DeepSeq import Data.Comp.Derive.Utils import Language.Haskell.TH-import Data.Maybe {-| Signature normal form. An instance @NFDataF f@ gives rise to an instance @NFData (Term f)@. -}@@ -33,26 +32,19 @@ kind taking at least one argument. -} makeNFDataF :: Name -> Q [Dec] makeNFDataF fname = do- TyConI (DataD _cxt name args constrs _deriving) <- abstractNewtypeQ $ reify fname- let fArg = VarT . tyVarBndrName $ last args- argNames = map (VarT . tyVarBndrName) (init args)+ Just (DataInfo _cxt name args constrs _deriving) <- abstractNewtypeQ $ reify fname+ let argNames = map (VarT . tyVarBndrName) (init args) complType = foldl AppT (ConT name) argNames- preCond = map (ClassP ''NFData . (: [])) argNames+ preCond = map (mkClassP ''NFData . (: [])) argNames classType = AppT (ConT ''NFDataF) complType constrs' <- mapM normalConExp constrs- rnfFDecl <- funD 'rnfF (rnfFClauses fArg constrs')- return [InstanceD preCond classType [rnfFDecl]]- where rnfFClauses fArg = map (genRnfFClause fArg)- filterFarg excl x- | excl = Nothing- | otherwise = Just $ varE x- mkPat True _ = WildP- mkPat False x = VarP x- genRnfFClause fArg (constr, args) = do - let isFargs = map (==fArg) args- n = length args+ rnfFDecl <- funD 'rnfF (rnfFClauses constrs')+ return [mkInstanceD preCond classType [rnfFDecl]]+ where rnfFClauses = map genRnfFClause+ genRnfFClause (constr, args,_) = do+ let n = length args varNs <- newNames n "x"- let pat = ConP constr $ zipWith mkPat isFargs varNs- allVars = catMaybes $ zipWith filterFarg isFargs varNs+ let pat = ConP constr [] $ map VarP varNs+ allVars = map varE varNs body <- foldr (\ x y -> [|rnf $x `seq` $y|]) [| () |] allVars return $ Clause [pat] (NormalB body) []
src/Data/Comp/Derive/Equality.hs view
@@ -31,30 +31,29 @@ taking at least one argument. -} makeEqF :: Name -> Q [Dec] makeEqF fname = do- TyConI (DataD _cxt name args constrs _deriving) <- abstractNewtypeQ $ reify fname+ Just (DataInfo _cxt name args constrs _deriving) <- abstractNewtypeQ $ reify fname let argNames = map (VarT . tyVarBndrName) (init args) complType = foldl AppT (ConT name) argNames- preCond = map (ClassP ''Eq . (: [])) argNames+ preCond = map (mkClassP ''Eq . (: [])) argNames classType = AppT (ConT ''EqF) complType eqFDecl <- funD 'eqF (eqFClauses constrs)- return [InstanceD preCond classType [eqFDecl]]+ return [mkInstanceD preCond classType [eqFDecl]] where eqFClauses constrs = map (genEqClause.abstractConType) constrs ++ defEqClause constrs- filterFarg fArg ty x = (fArg == ty, x) defEqClause constrs | length constrs < 2 = [] | otherwise = [clause [wildP,wildP] (normalB [|False|]) []]- genEqClause (constr, n) = do + genEqClause (constr, n) = do varNs <- newNames n "x" varNs' <- newNames n "y"- let pat = ConP constr $ map VarP varNs- pat' = ConP constr $ map VarP varNs'+ let pat = ConP constr [] $ map VarP varNs+ pat' = ConP constr [] $ map VarP varNs' vars = map VarE varNs vars' = map VarE varNs' mkEq x y = let (x',y') = (return x,return y) in [| $x' == $y'|] eqs = listE $ zipWith mkEq vars vars'- body <- if n == 0 + body <- if n == 0 then [|True|] else [|and $eqs|] return $ Clause [pat, pat'] (NormalB body) []
src/Data/Comp/Derive/Foldable.hs view
@@ -18,29 +18,28 @@ makeFoldable ) where +import Control.Monad import Data.Comp.Derive.Utils-import Language.Haskell.TH import Data.Foldable-import Control.Monad-import Data.Monoid import Data.Maybe-import qualified Prelude as P (foldl,foldr,foldl1,foldr1)-import Prelude hiding (foldl,foldr,foldl1,foldr1)+import Data.Monoid+import Language.Haskell.TH+import Prelude hiding (foldl, foldl1, foldr, foldr1)+import qualified Prelude as P (foldl, foldl1, foldr, foldr1) iter 0 _ e = e iter n f e = iter (n-1) f (f `appE` e) -iter' n f e = run n f e- where run 0 _ e = e- run m f e = let f' = iter (m-1) [|fmap|] f- in run (m-1) f (f' `appE` e)+iter' 0 _ e = e+iter' m f e = let f' = iter (m-1) [|fmap|] f+ in iter' (m-1) f (f' `appE` e) {-| Derive an instance of 'Foldable' for a type constructor of any first-order kind taking at least one argument. -} makeFoldable :: Name -> Q [Dec] makeFoldable fname = do- TyConI (DataD _cxt name args constrs _deriving) <- abstractNewtypeQ $ reify fname+ Just (DataInfo _cxt name args constrs _deriving) <- abstractNewtypeQ $ reify fname let fArg = VarT . tyVarBndrName $ last args argNames = map (VarT . tyVarBndrName) (init args) complType = foldl AppT (ConT name) argNames@@ -52,13 +51,13 @@ foldrDecl <- funD 'foldr (map foldrClause constrs') foldl1Decl <- funD 'foldl1 (map foldl1Clause constrs') foldr1Decl <- funD 'foldr1 (map foldr1Clause constrs')- return [InstanceD [] classType [foldDecl,foldMapDecl,foldlDecl,foldrDecl,foldl1Decl,foldr1Decl]]- where isFarg fArg (constr, args) = (constr, map (`containsType'` fArg) args)+ return [mkInstanceD [] classType [foldDecl,foldMapDecl,foldlDecl,foldrDecl,foldl1Decl,foldr1Decl]]+ where isFarg fArg (constr, args, gadtTy) = (constr, map (`containsType'` (getUnaryFArg fArg gadtTy)) args) filterVar [] _ = Nothing filterVar [d] x =Just (d, varE x) filterVar _ _ = error "functor variable occurring twice in argument type" filterVars args varNs = catMaybes $ zipWith filterVar args varNs- mkCPat constr args varNs = ConP constr $ zipWith mkPat args varNs+ mkCPat constr args varNs = ConP constr [] $ zipWith mkPat args varNs mkPat [] _ = WildP mkPat _ x = VarP x mkPatAndVars (constr, args) =@@ -78,7 +77,7 @@ fp = if null vars then WildP else VarP fn body <- case vars of [] -> [|mempty|]- (_:_) -> P.foldl1 (\ x y -> [|$x `mappend` $y|]) $ + (_:_) -> P.foldl1 (\ x y -> [|$x `mappend` $y|]) $ map (\ (d,z) -> iter' (max (d-1) 0) [|fold|] (f' d `appE` z)) vars return $ Clause [fp, pat] (NormalB body) [] foldlClause (pat,vars) =@@ -114,11 +113,11 @@ let f = varE fn fp = case vars of (d,_):r- | d > 0 || not (null r) -> VarP fn - _ -> WildP + | d > 0 || not (null r) -> VarP fn+ _ -> WildP mkComp (d,x) = iter' d [|foldl1 $f|] x- body <- case vars of - [] -> [|undefined|] + body <- case vars of+ [] -> [|undefined|] _ -> P.foldl1 (\ x y -> [|$f $x $y|]) $ map mkComp vars return $ Clause [fp, pat] (NormalB body) [] foldr1Clause (pat,vars) =@@ -126,10 +125,10 @@ let f = varE fn fp = case vars of (d,_):r- | d > 0 || not (null r) -> VarP fn - _ -> WildP + | d > 0 || not (null r) -> VarP fn+ _ -> WildP mkComp (d,x) = iter' d [|foldr1 $f|] x- body <- case vars of - [] -> [|undefined|] + body <- case vars of+ [] -> [|undefined|] _ -> P.foldr1 (\ x y -> [|$f $x $y|]) $ map mkComp vars return $ Clause [fp, pat] (NormalB body) []
src/Data/Comp/Derive/HaskellStrict.hs view
@@ -1,4 +1,8 @@-{-# LANGUAGE TemplateHaskell, TypeOperators, CPP #-}+{-# LANGUAGE CPP #-}+{-# LANGUAGE ConstraintKinds #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE TypeOperators #-} -------------------------------------------------------------------------------- -- | -- Module : Data.Comp.Derive.HaskellStrict@@ -19,29 +23,29 @@ , haskellStrict' ) where +import Control.Monad hiding (mapM, sequence) import Data.Comp.Derive.Utils-import Language.Haskell.TH-import Data.Maybe-import Data.Comp.Thunk import Data.Comp.Sum+import Data.Comp.Thunk+import Data.Foldable hiding (any, or)+import Data.Maybe import Data.Traversable-import Data.Foldable hiding (any,or)-import Control.Monad hiding (mapM, sequence)-import qualified Prelude as P (foldl, foldr, mapM, all)-import Prelude hiding (foldl, foldr,mapM, sequence)+import Language.Haskell.TH+import Prelude hiding (foldl, foldr, mapM, sequence)+import qualified Prelude as P (all, foldl, foldr, mapM) class HaskellStrict f where thunkSequence :: (Monad m) => f (TermT m g) -> m (f (TermT m g))- thunkSequenceInject :: (Monad m, f :<: g) => f (TermT m g) -> TermT m g+ thunkSequenceInject :: (Monad m, f :<: m :+: g) => f (TermT m g) -> TermT m g thunkSequenceInject t = thunk $ liftM inject $ thunkSequence t- thunkSequenceInject' :: (Monad m, f :<: g) => f (TermT m g) -> TermT m g+ thunkSequenceInject' :: (Monad m, f :<: m :+: g) => f (TermT m g) -> TermT m g thunkSequenceInject' = thunkSequenceInject -haskellStrict :: (Monad m, HaskellStrict f, f :<: g) => f (TermT m g) -> TermT m g+haskellStrict :: (Monad m, HaskellStrict f, f :<: m :+: g) => f (TermT m g) -> TermT m g haskellStrict = thunkSequenceInject -haskellStrict' :: (Monad m, HaskellStrict f, f :<: g) => f (TermT m g) -> TermT m g+haskellStrict' :: (Monad m, HaskellStrict f, f :<: m :+: g) => f (TermT m g) -> TermT m g haskellStrict' = thunkSequenceInject' deepThunk d = iter d [|thunkSequence|]@@ -53,7 +57,7 @@ first-order kind taking at least one argument. -} makeHaskellStrict :: Name -> Q [Dec] makeHaskellStrict fname = do- TyConI (DataD _cxt name args constrs _deriving) <- abstractNewtypeQ $ reify fname+ Just (DataInfo _cxt name args constrs _deriving) <- abstractNewtypeQ $ reify fname let fArg = VarT . tyVarBndrName $ last args argNames = map (VarT . tyVarBndrName) (init args) complType = foldl AppT (ConT name) argNames@@ -64,26 +68,31 @@ sequenceDecl <- valD (varP 'thunkSequence) (normalB [|return|]) [] injectDecl <- valD (varP 'thunkSequenceInject) (normalB [|inject|]) [] injectDecl' <- valD (varP 'thunkSequenceInject') (normalB [|inject|]) []- return [InstanceD [] classType [sequenceDecl, injectDecl, injectDecl']]+ return [mkInstanceD [] classType [sequenceDecl, injectDecl, injectDecl']] else do (sc',matchPat,ic') <- liftM unzip3 $ P.mapM mkClauses constrs_ xn <- newName "x" doThunk <- [|thunk|] let sequenceDecl = FunD 'thunkSequence sc'- injectDecl = FunD 'thunkSequenceInject [Clause [VarP xn] (NormalB (doThunk `AppE` CaseE (VarE xn) matchPat)) []] + injectDecl = FunD 'thunkSequenceInject [Clause [VarP xn] (NormalB (doThunk `AppE` CaseE (VarE xn) matchPat)) []] injectDecl' = FunD 'thunkSequenceInject' ic'- return [InstanceD [] classType [sequenceDecl, injectDecl, injectDecl']]- where isFarg fArg (constr, args) = (constr, map (containsStr fArg) args)- containsStr _ (NotStrict,_) = []+ return [mkInstanceD [] classType [sequenceDecl, injectDecl, injectDecl']]+ where isFarg fArg (constr, args, gadtTy) = (constr, map (containsStr (getUnaryFArg fArg gadtTy)) args)+ +#if __GLASGOW_HASKELL__ < 800 containsStr fArg (IsStrict,ty) = ty `containsType'` fArg-#if __GLASGOW_HASKELL__ > 702 containsStr fArg (Unpacked,ty) = ty `containsType'` fArg+#else+ containsStr fArg (Bang _ SourceStrict,ty) = ty `containsType'` fArg+ containsStr fArg (Bang SourceUnpack _,ty) = ty `containsType'` fArg #endif+ containsStr _ _ = []+ filterVar _ nonFarg [] x = nonFarg x filterVar farg _ [depth] x = farg depth x filterVar _ _ _ _ = error "functor variable occurring twice in argument type" filterVars args varNs farg nonFarg = zipWith (filterVar farg nonFarg) args varNs- mkCPat constr varNs = ConP constr $ map mkPat varNs+ mkCPat constr varNs = ConP constr [] $ map mkPat varNs mkPat = VarP mkClauses (constr, args) = do varNs <- newNames (length args) "x"@@ -91,7 +100,7 @@ fvars = catMaybes $ filterVars args varNs (curry Just) (const Nothing) allVars = map varE varNs conAp = P.foldl appE (conE constr) allVars- conBind (d, x) y = [| $(deepThunk d `appE` (varE x)) >>= $(lamE [varP x] y)|]+ conBind (d, x) y = [| $(deepThunk d `appE` varE x) >>= $(lamE [varP x] y)|] bodySC' <- P.foldr conBind [|return $conAp|] fvars let sc' = Clause [pat] (NormalB bodySC') [] bodyMatch <- case fvars of
− src/Data/Comp/Derive/Injections.hs
@@ -1,82 +0,0 @@-{-# LANGUAGE TemplateHaskell #-}------------------------------------------------------------------------------------ |--- Module : Data.Comp.Derive.Injections--- Copyright : (c) 2011 Patrick Bahr, Tom Hvitved--- License : BSD3--- Maintainer : Tom Hvitved <hvitved@diku.dk>--- Stability : experimental--- Portability : non-portable (GHC Extensions)------ Derive functions for signature injections.--------------------------------------------------------------------------------------module Data.Comp.Derive.Injections- (- injn,- injectn,- deepInjectn- ) where--import Language.Haskell.TH hiding (Cxt)-import Data.Comp.Term-import Data.Comp.Algebra (CxtFun, appSigFun)-import Data.Comp.Ops ((:+:)(..), (:<:)(..))--injn :: Int -> Q [Dec]-injn n = do- let i = mkName $ "inj" ++ show n- let fvars = map (\n -> mkName $ 'f' : show n) [1..n]- let gvar = mkName "g"- let avar = mkName "a"- let xvar = mkName "x"- let d = [funD i [clause [varP xvar] (normalB $ genDecl xvar n) []]]- sequence $ sigD i (genSig fvars gvar avar) : d- where genSig fvars gvar avar = do- let cxt = map (\f -> classP ''(:<:) [varT f, varT gvar]) fvars- let tp = foldl1 (\a f -> conT ''(:+:) `appT` f `appT` a)- (map varT fvars)- let tp' = arrowT `appT` (tp `appT` varT avar)- `appT` (varT gvar `appT` varT avar)- forallT (map PlainTV $ gvar : avar : fvars)- (sequence cxt) tp'- genDecl x n = [| case $(varE x) of- Inl x -> $(varE $ mkName "inj") x- Inr x -> $(varE $ mkName $ "inj" ++- if n > 2 then show (n - 1) else "") x |]-injectn :: Int -> Q [Dec]-injectn n = do- let i = mkName ("inject" ++ show n)- let fvars = map (\n -> mkName $ 'f' : show n) [1..n]- let gvar = mkName "g"- let avar = mkName "a"- let d = [funD i [clause [] (normalB $ genDecl n) []]]- sequence $ sigD i (genSig fvars gvar avar) : d- where genSig fvars gvar avar = do- let hvar = mkName "h"- let cxt = map (\f -> classP ''(:<:) [varT f, varT gvar]) fvars- let tp = foldl1 (\a f -> conT ''(:+:) `appT` f `appT` a)- (map varT fvars)- let tp' = conT ''Cxt `appT` varT hvar `appT` varT gvar- `appT` varT avar- let tp'' = arrowT `appT` (tp `appT` tp') `appT` tp'- forallT (map PlainTV $ hvar : gvar : avar : fvars)- (sequence cxt) tp''- genDecl n = [| Term . $(varE $ mkName $ "inj" ++ show n) |]--deepInjectn :: Int -> Q [Dec]-deepInjectn n = do- let i = mkName ("deepInject" ++ show n)- let fvars = map (\n -> mkName $ 'f' : show n) [1..n]- let gvar = mkName "g"- let d = [funD i [clause [] (normalB $ genDecl n) []]]- sequence $ sigD i (genSig fvars gvar) : d- where genSig fvars gvar = do- let cxt = map (\f -> classP ''(:<:) [varT f, varT gvar]) fvars- let tp = foldl1 (\a f -> conT ''(:+:) `appT` f `appT` a)- (map varT fvars)- let cxt' = classP ''Functor [tp]- let tp' = conT ''CxtFun `appT` tp `appT` varT gvar- forallT (map PlainTV $ gvar : fvars) (sequence $ cxt' : cxt) tp'- genDecl n = [| appSigFun $(varE $ mkName $ "inj" ++ show n) |]
src/Data/Comp/Derive/Ordering.hs view
@@ -20,8 +20,8 @@ import Data.Comp.Derive.Equality import Data.Comp.Derive.Utils -import Data.Maybe import Data.List+import Data.Maybe import Language.Haskell.TH hiding (Cxt) {-| Signature ordering. An instance @OrdF f@ gives rise to an instance@@ -29,7 +29,7 @@ class EqF f => OrdF f where compareF :: Ord a => f a -> f a -> Ordering - + compList :: [Ordering] -> Ordering compList = fromMaybe EQ . find (/= EQ) @@ -37,15 +37,15 @@ taking at least one argument. -} makeOrdF :: Name -> Q [Dec] makeOrdF fname = do- TyConI (DataD _cxt name args constrs _deriving) <- abstractNewtypeQ $ reify fname+ Just (DataInfo _cxt name args constrs _deriving) <- abstractNewtypeQ $ reify fname let argNames = map (VarT . tyVarBndrName) (init args) complType = foldl AppT (ConT name) argNames- preCond = map (ClassP ''Ord . (: [])) argNames+ preCond = map (mkClassP ''Ord . (: [])) argNames classType = AppT (ConT ''OrdF) complType eqAlgDecl <- funD 'compareF (compareFClauses constrs)- return [InstanceD preCond classType [eqAlgDecl]]+ return [mkInstanceD preCond classType [eqAlgDecl]] where compareFClauses [] = []- compareFClauses constrs = + compareFClauses constrs = let constrs' = map abstractConType constrs `zip` [1..] constPairs = [(x,y)| x<-constrs', y <- constrs'] in map genClause constPairs@@ -53,11 +53,11 @@ | n == m = genEqClause c | n < m = genLtClause c d | otherwise = genGtClause c d- genEqClause (constr, n) = do + genEqClause (constr, n) = do varNs <- newNames n "x" varNs' <- newNames n "y"- let pat = ConP constr $ map VarP varNs- pat' = ConP constr $ map VarP varNs'+ let pat = ConP constr [] $ map VarP varNs+ pat' = ConP constr [] $ map VarP varNs' vars = map VarE varNs vars' = map VarE varNs' mkEq x y = let (x',y') = (return x,return y)
− src/Data/Comp/Derive/Projections.hs
@@ -1,95 +0,0 @@-{-# LANGUAGE TemplateHaskell, GADTs #-}------------------------------------------------------------------------------------ |--- Module : Data.Comp.Derive.Projections--- Copyright : (c) 2011 Patrick Bahr, Tom Hvitved--- License : BSD3--- Maintainer : Tom Hvitved <hvitved@diku.dk>--- Stability : experimental--- Portability : non-portable (GHC Extensions)------ Derive functions for signature projections.--------------------------------------------------------------------------------------module Data.Comp.Derive.Projections- (- projn,- projectn,- deepProjectn- ) where--import Language.Haskell.TH hiding (Cxt)-import Control.Monad (liftM)-import Data.Traversable (Traversable)-import Data.Comp.Term-import Data.Comp.Algebra (CxtFunM, appSigFunM')-import Data.Comp.Ops ((:+:)(..), (:<:)(..))--projn :: Int -> Q [Dec]-projn n = do- let p = mkName $ "proj" ++ show n- let gvars = map (\n -> mkName $ 'g' : show n) [1..n]- let avar = mkName "a"- let xvar = mkName "x"- let d = [funD p [clause [varP xvar] (normalB $ genDecl xvar gvars avar) []]]- sequence $ (sigD p $ genSig gvars avar) : d- where genSig gvars avar = do- let fvar = mkName "f"- let cxt = map (\g -> classP ''(:<:) [varT g, varT fvar]) gvars- let tp = foldl1 (\a g -> conT ''(:+:) `appT` g `appT` a)- (map varT gvars)- let tp' = arrowT `appT` (varT fvar `appT` varT avar)- `appT` (conT ''Maybe `appT`- (tp `appT` varT avar))- forallT (map PlainTV $ fvar : avar : gvars) (sequence cxt) tp'- genDecl x [g] a =- [| liftM inj (proj $(varE x)- :: Maybe ($(varT g `appT` varT a))) |]- genDecl x (g:gs) a =- [| case (proj $(varE x)- :: Maybe ($(varT g `appT` varT a))) of- Just y -> Just $ inj y- _ -> $(genDecl x gs a) |]- genDecl _ _ _ = error "genDecl called with empty list"--projectn :: Int -> Q [Dec]-projectn n = do- let p = mkName ("project" ++ show n)- let gvars = map (\n -> mkName $ 'g' : show n) [1..n]- let avar = mkName "a"- let xvar = mkName "x"- let d = [funD p [clause [varP xvar] (normalB $ genDecl xvar n) []]]- sequence $ (sigD p $ genSig gvars avar) : d- where genSig gvars avar = do- let fvar = mkName "f"- let hvar = mkName "h"- let cxt = map (\g -> classP ''(:<:) [varT g, varT fvar]) gvars- let tp = foldl1 (\a g -> conT ''(:+:) `appT` g `appT` a)- (map varT gvars)- let tp' = conT ''Cxt `appT` varT hvar `appT` varT fvar- `appT` varT avar- let tp'' = arrowT `appT` tp'- `appT` (conT ''Maybe `appT` (tp `appT` tp'))- forallT (map PlainTV $ hvar : fvar : avar : gvars)- (sequence cxt) tp''- genDecl x n = [| case $(varE x) of- Hole _ -> Nothing- Term t -> $(varE $ mkName $ "proj" ++ show n) t |]--deepProjectn :: Int -> Q [Dec]-deepProjectn n = do- let p = mkName ("deepProject" ++ show n)- let gvars = map (\n -> mkName $ 'g' : show n) [1..n]- let d = [funD p [clause [] (normalB $ genDecl n) []]]- sequence $ (sigD p $ genSig gvars) : d- where genSig gvars = do- let fvar = mkName "f"- let cxt = map (\g -> classP ''(:<:) [varT g, varT fvar]) gvars- let tp = foldl1 (\a g -> conT ''(:+:) `appT` g `appT` a)- (map varT gvars)- let cxt' = classP ''Traversable [tp]- let tp' = conT ''CxtFunM `appT` conT ''Maybe- `appT` varT fvar `appT` tp- forallT (map PlainTV $ fvar : gvars) (sequence $ cxt' : cxt) tp'- genDecl n = [| appSigFunM' $(varE $ mkName $ "proj" ++ show n) |]
src/Data/Comp/Derive/Show.hs view
@@ -15,7 +15,9 @@ module Data.Comp.Derive.Show ( ShowF(..),- makeShowF+ makeShowF,+ ShowConstr(..),+ makeShowConstr ) where import Data.Comp.Derive.Utils@@ -25,36 +27,72 @@ @Show (Term f)@. -} class ShowF f where showF :: f String -> String- -showConstr :: String -> [String] -> String-showConstr con [] = con-showConstr con args = "(" ++ con ++ " " ++ unwords args ++ ")" +showCon :: String -> [String] -> String+showCon con [] = con+showCon con args = "(" ++ con ++ " " ++ unwords args ++ ")"+ {-| Derive an instance of 'ShowF' for a type constructor of any first-order kind taking at least one argument. -} makeShowF :: Name -> Q [Dec] makeShowF fname = do- TyConI (DataD _cxt name args constrs _deriving) <- abstractNewtypeQ $ reify fname+ Just (DataInfo _cxt name args constrs _deriving) <- abstractNewtypeQ $ reify fname let fArg = VarT . tyVarBndrName $ last args argNames = map (VarT . tyVarBndrName) (init args) complType = foldl AppT (ConT name) argNames- preCond = map (ClassP ''Show . (: [])) argNames+ preCond = map (mkClassP ''Show . (: [])) argNames classType = AppT (ConT ''ShowF) complType constrs' <- mapM normalConExp constrs showFDecl <- funD 'showF (showFClauses fArg constrs')- return [InstanceD preCond classType [showFDecl]]+ return [mkInstanceD preCond classType [showFDecl]] where showFClauses fArg = map (genShowFClause fArg) filterFarg fArg ty x = (fArg == ty, varE x) mkShow :: (Bool, ExpQ) -> ExpQ mkShow (isFArg, var) | isFArg = var | otherwise = [| show $var |]- genShowFClause fArg (constr, args) = do + genShowFClause fArg (constr, args, gadtTy) = do let n = length args varNs <- newNames n "x"- let pat = ConP constr $ map VarP varNs- allVars = zipWith (filterFarg fArg) args varNs+ let pat = ConP constr [] $ map VarP varNs+ allVars = zipWith (filterFarg (getUnaryFArg fArg gadtTy)) args varNs shows = listE $ map mkShow allVars conName = nameBase constr- body <- [|showConstr conName $shows|]+ body <- [|showCon conName $shows|]+ return $ Clause [pat] (NormalB body) []++{-| Constructor printing. -}+class ShowConstr f where+ showConstr :: f a -> String++showCon' :: String -> [String] -> String+showCon' con args = unwords $ con : filter (not.null) args++{-| Derive an instance of 'showConstr' for a type constructor of any first-order kind+ taking at least one argument. -}+makeShowConstr :: Name -> Q [Dec]+makeShowConstr fname = do+ Just (DataInfo _cxt name args constrs _deriving) <- abstractNewtypeQ $ reify fname+ let fArg = VarT . tyVarBndrName $ last args+ argNames = map (VarT . tyVarBndrName) (init args)+ complType = foldl AppT (ConT name) argNames+ preCond = map (mkClassP ''Show . (: [])) argNames+ classType = AppT (ConT ''ShowConstr) complType+ constrs' <- mapM normalConExp constrs+ showConstrDecl <- funD 'showConstr (showConstrClauses fArg constrs')+ return [mkInstanceD preCond classType [showConstrDecl]]+ where showConstrClauses fArg = map (genShowConstrClause fArg)+ filterFarg fArg ty x = (fArg == ty, varE x)+ mkShow :: (Bool, ExpQ) -> ExpQ+ mkShow (isFArg, var)+ | isFArg = [| "" |]+ | otherwise = [| show $var |]+ genShowConstrClause fArg (constr, args, gadtTy) = do+ let n = length args+ varNs <- newNames n "x"+ let pat = ConP constr [] $ map VarP varNs+ allVars = zipWith (filterFarg (getUnaryFArg fArg gadtTy)) args varNs+ shows = listE $ map mkShow allVars+ conName = nameBase constr+ body <- [|showCon' conName $shows|] return $ Clause [pat] (NormalB body) []
src/Data/Comp/Derive/SmartAConstructors.hs view
@@ -17,12 +17,12 @@ smartAConstructors ) where -import Language.Haskell.TH hiding (Cxt)+import Control.Monad+import Data.Comp.Annotation import Data.Comp.Derive.Utils import Data.Comp.Sum import Data.Comp.Term-import Data.Comp.Annotation-import Control.Monad+import Language.Haskell.TH hiding (Cxt) {-| Derive smart constructors with products for a type constructor of any parametric kind taking at least one argument. The smart constructors are@@ -30,13 +30,13 @@ inserted. -} smartAConstructors :: Name -> Q [Dec] smartAConstructors fname = do- TyConI (DataD _cxt tname targs constrs _deriving) <- abstractNewtypeQ $ reify fname+ Just (DataInfo _cxt _tname _targs constrs _deriving) <- abstractNewtypeQ $ reify fname let cons = map abstractConType constrs- liftM concat $ mapM (genSmartConstr (map tyVarBndrName targs) tname) cons- where genSmartConstr targs tname (name, args) = do+ liftM concat $ mapM genSmartConstr cons+ where genSmartConstr (name, args) = do let bname = nameBase name- genSmartConstr' targs tname (mkName $ "iA" ++ bname) name args- genSmartConstr' targs tname sname name args = do+ genSmartConstr' (mkName $ "iA" ++ bname) name args+ genSmartConstr' sname name args = do varNs <- newNames args "x" varPr <- newName "_p" let pats = map varP (varPr : varNs)
src/Data/Comp/Derive/SmartConstructors.hs view
@@ -12,23 +12,23 @@ -- -------------------------------------------------------------------------------- -module Data.Comp.Derive.SmartConstructors +module Data.Comp.Derive.SmartConstructors ( smartConstructors ) where -import Language.Haskell.TH hiding (Cxt)+import Control.Monad import Data.Comp.Derive.Utils import Data.Comp.Sum import Data.Comp.Term-import Control.Monad+import Language.Haskell.TH hiding (Cxt) {-| Derive smart constructors for a type constructor of any first-order kind taking at least one argument. The smart constructors are similar to the ordinary constructors, but an 'inject' is automatically inserted. -} smartConstructors :: Name -> Q [Dec] smartConstructors fname = do- TyConI (DataD _cxt tname targs constrs _deriving) <- abstractNewtypeQ $ reify fname+ Just (DataInfo _cxt tname targs constrs _deriving) <- abstractNewtypeQ $ reify fname let cons = map abstractConType constrs liftM concat $ mapM (genSmartConstr (map tyVarBndrName targs) tname) cons where genSmartConstr targs tname (name, args) = do@@ -52,8 +52,8 @@ h = varT hvar a = varT avar ftype = foldl appT (conT tname) (map varT targs')- constr = classP ''(:<:) [ftype, f]+ constr = (conT ''(:<:) `appT` ftype) `appT` f typ = foldl appT (conT ''Cxt) [h, f, a]- typeSig = forallT (map PlainTV vars) (sequence [constr]) typ+ typeSig = forallT (map (\ v -> PlainTV v SpecifiedSpec) vars) (sequence [constr]) typ sigD sname typeSig genSig _ _ _ _ = []
src/Data/Comp/Derive/Traversable.hs view
@@ -18,29 +18,28 @@ makeTraversable ) where +import Control.Applicative+import Control.Monad hiding (mapM, sequence) import Data.Comp.Derive.Utils-import Language.Haskell.TH+import Data.Foldable hiding (any, or) import Data.Maybe import Data.Traversable-import Data.Foldable hiding (any,or)-import Control.Applicative-import Control.Monad hiding (mapM, sequence)+import Language.Haskell.TH+import Prelude hiding (foldl, foldr, mapM, sequence) import qualified Prelude as P (foldl, foldr, mapM)-import Prelude hiding (foldl, foldr,mapM, sequence) iter 0 _ e = e iter n f e = iter (n-1) f (f `appE` e) -iter' n f e = run n f e- where run 0 _ e = e- run m f e = let f' = iter (m-1) [|fmap|] f- in run (m-1) f (f' `appE` e)+iter' 0 _ e = e+iter' m f e = let f' = iter (m-1) [|fmap|] f+ in iter' (m-1) f (f' `appE` e) {-| Derive an instance of 'Traversable' for a type constructor of any first-order kind taking at least one argument. -} makeTraversable :: Name -> Q [Dec] makeTraversable fname = do- TyConI (DataD _cxt name args constrs _deriving) <- abstractNewtypeQ $ reify fname+ Just (DataInfo _cxt name args constrs _deriving) <- abstractNewtypeQ $ reify fname let fArg = VarT . tyVarBndrName $ last args argNames = map (VarT . tyVarBndrName) (init args) complType = foldl AppT (ConT name) argNames@@ -50,27 +49,27 @@ sequenceADecl <- funD 'sequenceA (map sequenceAClause constrs') mapMDecl <- funD 'mapM (map mapMClause constrs') sequenceDecl <- funD 'sequence (map sequenceClause constrs')- return [InstanceD [] classType [traverseDecl, sequenceADecl, mapMDecl,sequenceDecl]]- where isFarg fArg (constr, args) = (constr, map (`containsType'` fArg) args)+ return [mkInstanceD [] classType [traverseDecl, sequenceADecl, mapMDecl,sequenceDecl]]+ where isFarg fArg (constr, args, gadtTy) = (constr, map (`containsType'` (getUnaryFArg fArg gadtTy)) args) filterVar _ nonFarg [] x = nonFarg x filterVar farg _ [depth] x = farg depth x filterVar _ _ _ _ = error "functor variable occurring twice in argument type" filterVars args varNs farg nonFarg = zipWith (filterVar farg nonFarg) args varNs- mkCPat constr varNs = ConP constr $ map mkPat varNs+ mkCPat constr varNs = ConP constr [] $ map mkPat varNs mkPat = VarP mkPatAndVars (constr, args) = do varNs <- newNames (length args) "x" return (conE constr, mkCPat constr varNs, \f g -> filterVars args varNs (\ d x -> f d (varE x)) (g . varE), any (not . null) args, map varE varNs, catMaybes $ filterVars args varNs (curry Just) (const Nothing))- traverseClause (con, pat,vars',hasFargs,_,_) =+ traverseClause (con, pat,vars',hasFargs,_allVars,_fVars) = do fn <- newName "f" let f = varE fn fp = if hasFargs then VarP fn else WildP vars = vars' (\d x -> iter d [|traverse|] f `appE` x) (\x -> [|pure $x|]) body <- P.foldl (\ x y -> [|$x <*> $y|]) [|pure $con|] vars return $ Clause [fp, pat] (NormalB body) []- sequenceAClause (con, pat,vars',hasFargs,_,_) =+ sequenceAClause (con, pat,vars',_hasFargs,_,_) = do let vars = vars' (\d x -> iter' d [|sequenceA|] x) (\x -> [|pure $x|]) body <- P.foldl (\ x y -> [|$x <*> $y|]) [|pure $con|] vars return $ Clause [pat] (NormalB body) []@@ -85,7 +84,7 @@ conBind (d,x) y = [| $(iter d [|mapM|] f) $(varE x) >>= $(lamE [varP x] y)|] body <- P.foldr conBind [|return $conAp|] fvars return $ Clause [fp, pat] (NormalB body) []- sequenceClause (con, pat,_,hasFargs,allVars, fvars) =+ sequenceClause (con, pat,_vars',_hasFargs,allVars, fvars) = do let conAp = P.foldl appE con allVars conBind (d, x) y = [| $(iter' d [|sequence|] (varE x)) >>= $(lamE [varP x] y)|] body <- P.foldr conBind [|return $conAp|] fvars
src/Data/Comp/Derive/Utils.hs view
@@ -1,3 +1,4 @@+{-# LANGUAGE ExistentialQuantification #-} {-# LANGUAGE CPP #-} -------------------------------------------------------------------------------- -- |@@ -15,61 +16,87 @@ module Data.Comp.Derive.Utils where +import Control.Monad import Language.Haskell.TH import Language.Haskell.TH.Syntax-import Control.Monad import Language.Haskell.TH.ExpandSyns --- reportError is introduced only from version 7.6 of GHC-#if __GLASGOW_HASKELL__ < 706-reportError :: String -> Q ()-reportError = report True-#endif+data DataInfo = forall flag . DataInfo Cxt Name [TyVarBndr flag] [Con] [DerivClause] + {-|- This is the @Q@-lifted version of 'abstractNewtypeQ.+ This is the @Q@-lifted version of 'abstractNewtype. -}-abstractNewtypeQ :: Q Info -> Q Info+abstractNewtypeQ :: Q Info -> Q (Maybe DataInfo) abstractNewtypeQ = liftM abstractNewtype {-| This function abstracts away @newtype@ declaration, it turns them into @data@ declarations. -}-abstractNewtype :: Info -> Info-abstractNewtype (TyConI (NewtypeD cxt name args constr derive))- = TyConI (DataD cxt name args [constr] derive)-abstractNewtype owise = owise+abstractNewtype :: Info -> Maybe DataInfo+abstractNewtype (TyConI (NewtypeD cxt name args _ constr derive))+ = Just (DataInfo cxt name args [constr] derive)+abstractNewtype (TyConI (DataD cxt name args _ constrs derive))+ = Just (DataInfo cxt name args constrs derive)+abstractNewtype _ = Nothing -{-|- This function provides the name and the arity of the given data constructor.+{-| This function provides the name and the arity of the given data+constructor, and if it is a GADT also its type. -}-normalCon :: Con -> (Name,[StrictType])-normalCon (NormalC constr args) = (constr, args)-normalCon (RecC constr args) = (constr, map (\(_,s,t) -> (s,t)) args)-normalCon (InfixC a constr b) = (constr, [a,b])+normalCon :: Con -> (Name,[StrictType], Maybe Type)+normalCon (NormalC constr args) = (constr, args, Nothing)+normalCon (RecC constr args) = (constr, map (\(_,s,t) -> (s,t)) args, Nothing)+normalCon (InfixC a constr b) = (constr, [a,b], Nothing) normalCon (ForallC _ _ constr) = normalCon constr+normalCon (GadtC (constr:_) args typ) = (constr,args,Just typ)+normalCon _ = error "missing case for 'normalCon'" +normalCon' :: Con -> (Name,[Type], Maybe Type)+normalCon' con = (n, map snd ts, t)+ where (n, ts, t) = normalCon con+ -normalCon' :: Con -> (Name,[Type])-normalCon' = fmap (map snd) . normalCon +-- -- | Same as normalCon' but expands type synonyms.+-- normalConExp :: Con -> Q (Name,[Type])+-- normalConExp c = do+-- let (n,ts,t) = normalCon' c+-- ts' <- mapM expandSyns ts+-- return (n, ts') -- | Same as normalCon' but expands type synonyms.-normalConExp :: Con -> Q (Name,[Type])-normalConExp c = do - let (n,ts) = normalCon' c- ts' <- mapM expandSyns ts- return (n, ts')+normalConExp :: Con -> Q (Name,[Type], Maybe Type)+normalConExp c = do+ let (n,ts,t) = normalCon' c+ return (n, ts,t) -- | Same as normalConExp' but retains strictness annotations.-normalConStrExp :: Con -> Q (Name,[StrictType])-normalConStrExp c = do - let (n,ts) = normalCon c+normalConStrExp :: Con -> Q (Name,[StrictType], Maybe Type)+normalConStrExp c = do+ let (n,ts,t) = normalCon c ts' <- mapM (\ (st,ty) -> do ty' <- expandSyns ty; return (st,ty')) ts- return (n, ts')+ return (n, ts',t) +-- | Auxiliary function to extract the first argument of a binary type+-- application (the second argument of this function). If the second+-- argument is @Nothing@ or not of the right shape, the first argument+-- is returned as a default. +getBinaryFArg :: Type -> Maybe Type -> Type+getBinaryFArg _ (Just (AppT (AppT _ t) _)) = t+getBinaryFArg def _ = def++-- | Auxiliary function to extract the first argument of a type+-- application (the second argument of this function). If the second+-- argument is @Nothing@ or not of the right shape, the first argument+-- is returned as a default.+getUnaryFArg :: Type -> Maybe Type -> Type+getUnaryFArg _ (Just (AppT _ t)) = t+getUnaryFArg def _ = def+++ {-| This function provides the name and the arity of the given data constructor. -}@@ -78,12 +105,14 @@ abstractConType (RecC constr args) = (constr, length args) abstractConType (InfixC _ constr _) = (constr, 2) abstractConType (ForallC _ _ constr) = abstractConType constr+abstractConType (GadtC (constr:_) args _typ) = (constr,length args) -- Only first Name+abstractConType _ = error "missing case for 'abstractConType'" {-| This function returns the name of a bound type variable -}-tyVarBndrName (PlainTV n) = n-tyVarBndrName (KindedTV n _) = n+tyVarBndrName (PlainTV n _) = n+tyVarBndrName (KindedTV n _ _) = n containsType :: Type -> Type -> Bool containsType s t@@ -125,6 +154,26 @@ derive :: [Name -> Q [Dec]] -> [Name] -> Q [Dec] derive ders names = liftM concat $ sequence [der name | der <- ders, name <- names] +{-| Apply a class name to type arguments to construct a type class+ constraint.+-}++mkClassP :: Name -> [Type] -> Type+mkClassP name = foldl AppT (ConT name)++{-| This function checks whether the given type constraint is an+equality constraint. If so, the types of the equality constraint are+returned. -}++isEqualP :: Type -> Maybe (Type, Type)+isEqualP (AppT (AppT EqualityT x) y) = Just (x, y)+isEqualP _ = Nothing++mkInstanceD :: Cxt -> Type -> [Dec] -> Dec+mkInstanceD cxt ty decs = InstanceD Nothing cxt ty decs+++ -- | This function lifts type class instances over sums -- ofsignatures. To this end it assumes that it contains only methods -- with types of the form @f t1 .. tn -> t@ where @f@ is the signature@@ -146,7 +195,7 @@ ClassI (ClassD _ name targs_ _ decs) _ <- reify fname let targs = map tyVarBndrName targs_ splitM <- findSig targs decs- case splitM of + case splitM of Nothing -> do reportError $ "Class " ++ show name ++ " cannot be lifted to sums!" return [] Just (ts1_, ts2_) -> do@@ -154,12 +203,12 @@ let g = VarT $ mkName "g" let ts1 = map VarT ts1_ let ts2 = map VarT ts2_- let cxt = [ClassP name (ts1 ++ f : ts2),- ClassP name (ts1 ++ g : ts2)]+ let cxt = [mkClassP name (ts1 ++ f : ts2),+ mkClassP name (ts1 ++ g : ts2)] let tp = ((ConT sumName `AppT` f) `AppT` g) let complType = foldl AppT (foldl AppT (ConT name) ts1 `AppT` tp) ts2 decs' <- sequence $ concatMap decl decs- return [InstanceD cxt complType decs']+ return [mkInstanceD cxt complType decs'] where decl :: Dec -> [DecQ] decl (SigD f _) = [funD f [clause f]] decl _ = []@@ -167,8 +216,8 @@ clause f = do x <- newName "x" let b = NormalB (VarE caseName `AppE` VarE f `AppE` VarE f `AppE` VarE x) return $ Clause [VarP x] b []- - ++ findSig :: [Name] -> [Dec] -> Q (Maybe ([Name],[Name])) findSig targs decs = case map run decs of [] -> return Nothing@@ -177,7 +226,7 @@ Nothing -> return Nothing Just n -> return $ splitNames n targs where run :: Dec -> Q (Maybe Name)- run (SigD _ ty) = do + run (SigD _ ty) = do ty' <- expandSyns ty return $ getSig False ty' run _ = return Nothing@@ -186,7 +235,7 @@ getSig True (AppT ty _) = getSig True ty getSig True (VarT n) = Just n getSig _ _ = Nothing- splitNames y (x:xs) + splitNames y (x:xs) | y == x = Just ([],xs) | otherwise = do (xs1,xs2) <- splitNames y xs return (x:xs1,xs2)
src/Data/Comp/Desugar.hs view
@@ -1,5 +1,9 @@-{-# LANGUAGE TemplateHaskell, MultiParamTypeClasses, FlexibleInstances,- UndecidableInstances, OverlappingInstances, TypeOperators #-}+{-# LANGUAGE ConstraintKinds #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE TypeOperators #-}+{-# LANGUAGE UndecidableInstances #-} -------------------------------------------------------------------------------- -- | -- Module : Data.Comp.Desugar@@ -26,7 +30,7 @@ -- We make the lifting to sums explicit in order to make the Desugar -- class work with the default instance declaration further below.-instance (Desugar f h, Desugar g h) => Desugar (f :+: g) h where+instance {-# OVERLAPPABLE #-} (Desugar f h, Desugar g h) => Desugar (f :+: g) h where desugHom = caseF desugHom desugHom -- |Desugar a term.@@ -40,5 +44,5 @@ desugarA = appHom (propAnn desugHom) -- |Default desugaring instance.-instance (Functor f, Functor g, f :<: g) => Desugar f g where+instance {-# OVERLAPPABLE #-} (Functor f, Functor g, f :<: g) => Desugar f g where desugHom = simpCxt . inj
src/Data/Comp/Equality.hs view
@@ -1,4 +1,6 @@-{-# LANGUAGE TypeOperators, GADTs, TemplateHaskell #-}+{-# LANGUAGE GADTs #-}+{-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE TypeOperators #-} -------------------------------------------------------------------------------- -- | -- Module : Data.Comp.Equality@@ -18,14 +20,13 @@ eqMod, ) where -import Data.Comp.Term-import Data.Comp.Sum-import Data.Comp.Ops+import Control.Monad hiding (mapM_) import Data.Comp.Derive.Equality import Data.Comp.Derive.Utils+import Data.Comp.Ops+import Data.Comp.Term import Data.Foldable-import Control.Monad hiding (mapM_)-import Prelude hiding (mapM_, all)+import Prelude hiding (all, mapM_) -- instance (EqF f, Eq p) => EqF (f :*: p) where -- eqF (v1 :*: p1) (v2 :*: p2) = p1 == p2 && v1 `eqF` v2
src/Data/Comp/Generic.hs view
@@ -1,4 +1,8 @@-{-# LANGUAGE GADTs, ScopedTypeVariables, TypeOperators #-}+{-# LANGUAGE ConstraintKinds #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE GADTs #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeOperators #-} -------------------------------------------------------------------------------- -- |@@ -16,15 +20,29 @@ module Data.Comp.Generic where -import Data.Comp.Term+import Control.Monad hiding (mapM)+import Data.Comp.Algebra import Data.Comp.Sum+import Data.Comp.Term import Data.Foldable import Data.Maybe import Data.Traversable-import GHC.Exts-import Control.Monad hiding (mapM)-import Prelude hiding (foldl,mapM)+import GHC.Exts (build)+import Prelude hiding (foldl, mapM) ++-- | This function returns the subterm of a given term at the position+-- specified by the given path or @Nothing@ if the input term has no+-- such subterm++getSubterm :: (Functor g, Foldable g) => [Int] -> Term g -> Maybe (Term g)+getSubterm path t = cata alg t path where+ alg :: (Functor g, Foldable g) => Alg g ([Int] -> Maybe (Cxt h g a))+ alg t [] = Just $ Term $ fmap ((fromJust) . ($ [])) t+ alg t (i:is) = case drop i (toList t) of+ [] -> Nothing+ x : _ -> x is+ -- | This function returns a list of all subterms of the given -- term. This function is similar to Uniplate's @universe@ function. subterms :: forall f . Foldable f => Term f -> [Term f]@@ -60,11 +78,11 @@ -- | Monadic version of 'transform'. transformM :: (Traversable f, Monad m) => (Term f -> m (Term f)) -> Term f -> m (Term f)-transformM f = run +transformM f = run where run t = f =<< liftM Term (mapM run $ unTerm t) query :: Foldable f => (Term f -> r) -> (r -> r -> r) -> Term f -> r-query q c = run +query q c = run where run i@(Term t) = foldl (\s x -> s `c` run x) (q i) t -- query q c i@(Term t) = foldl (\s x -> s `c` query q c x) (q i) t
+ src/Data/Comp/Mapping.hs view
@@ -0,0 +1,102 @@+{-# LANGUAGE TupleSections #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE FunctionalDependencies #-}+{-# LANGUAGE GeneralizedNewtypeDeriving #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE DeriveTraversable #-}+{-# LANGUAGE DeriveFoldable #-}+--------------------------------------------------------------------------------+-- |+-- Module : Data.Comp.Mapping+-- Copyright : (c) 2014 Patrick Bahr+-- License : BSD3+-- Maintainer : Patrick Bahr <paba@diku.dk>+-- Stability : experimental+-- Portability : non-portable (GHC Extensions)+--+-- This module provides functionality to construct mappings from+-- positions in a functorial value.+--+--------------------------------------------------------------------------------++module Data.Comp.Mapping+ ( Numbered (..)+ , unNumbered+ , number+ , Traversable ()+ , Mapping (..)+ , prodMap+ , lookupNumMap+ , lookupNumMap'+ , NumMap) where++import Data.IntMap (IntMap)+import qualified Data.IntMap as IntMap+import Data.Traversable+import Data.Foldable++import Control.Monad.State+import Prelude hiding (mapM)+++-- | This type is used for numbering components of a functorial value.+data Numbered a = Numbered Int a++unNumbered :: Numbered a -> a+unNumbered (Numbered _ x) = x+++-- | This function numbers the components of the given functorial+-- value with consecutive integers starting at 0.+number :: Traversable f => f a -> f (Numbered a)+number x = evalState (mapM run x) 0 where+ run b = do n <- get+ put (n+1)+ return $ Numbered n b+++infix 1 |->+infixr 0 &+++class Functor m => Mapping m k | m -> k where+ -- | left-biased union of two mappings.+ (&) :: m v -> m v -> m v++ -- | This operator constructs a singleton mapping.+ (|->) :: k -> v -> m v++ -- | This is the empty mapping.+ empty :: m v++ -- | This function constructs the pointwise product of two maps each+ -- with a default value.+ prodMapWith :: (v1 -> v2 -> v) -> v1 -> v2 -> m v1 -> m v2 -> m v++ -- | Returns the value at the given key or returns the given+ -- default when the key is not an element of the map.+ findWithDefault :: a -> k -> m a -> a++-- | This function constructs the pointwise product of two maps each+-- with a default value.+prodMap :: Mapping m k => v1 -> v2 -> m v1 -> m v2 -> m (v1, v2)+prodMap = prodMapWith (,)++newtype NumMap k v = NumMap (IntMap v) deriving (Functor,Foldable,Traversable)++lookupNumMap :: a -> Int -> NumMap t a -> a+lookupNumMap d k (NumMap m) = IntMap.findWithDefault d k m++lookupNumMap' :: Int -> NumMap t a -> Maybe a+lookupNumMap' k (NumMap m) = IntMap.lookup k m++instance Mapping (NumMap k) (Numbered k) where+ NumMap m1 & NumMap m2 = NumMap (IntMap.union m1 m2)+ Numbered k _ |-> v = NumMap $ IntMap.singleton k v+ empty = NumMap IntMap.empty++ findWithDefault d (Numbered i _) m = lookupNumMap d i m++ prodMapWith f p q (NumMap mp) (NumMap mq) = NumMap $ IntMap.mergeWithKey merge + (IntMap.map (`f` q)) (IntMap.map (p `f`)) mp mq+ where merge _ p q = Just (p `f` q)
src/Data/Comp/Matching.hs view
@@ -1,4 +1,6 @@-{-# LANGUAGE GADTs, FlexibleContexts #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE GADTs #-}+{-# LANGUAGE MultiParamTypeClasses #-} -------------------------------------------------------------------------------- -- | -- Module : Data.Comp.Matching@@ -19,15 +21,15 @@ module Data.Comp.Variables ) where -import Data.Comp.Term import Data.Comp.Equality+import Data.Comp.Term import Data.Comp.Variables-import qualified Data.Map as Map+import Data.Foldable import Data.Map (Map)+import qualified Data.Map as Map import Data.Traversable-import Data.Foldable -import Prelude hiding (mapM_, mapM, all)+import Prelude hiding (all, mapM, mapM_) {-| This is an auxiliary function for implementing 'matchCxt'. It behaves similarly as 'match' but is oblivious to non-linearity. Therefore, the@@ -58,7 +60,7 @@ matchCxt :: (Ord v,EqF f, Eq (Cxt h f a), Functor f, Foldable f) => Context f v -> Cxt h f a -> Maybe (CxtSubst h a f v)-matchCxt c1 c2 = do +matchCxt c1 c2 = do res <- matchCxt' c1 c2 let insts = Map.elems res mapM_ checkEq insts
src/Data/Comp/Multi.hs view
@@ -8,7 +8,7 @@ -- Portability : non-portable (GHC Extensions) -- -- This module defines the infrastructure necessary to use--- /Generalised Compositional Data Types/. Generalised Compositional Data Types +-- /Generalised Compositional Data Types/. Generalised Compositional Data Types -- is an extension of Compositional Data Types with mutually recursive -- data types, and more generally GADTs. Examples of usage are bundled with the -- package in the library @examples\/Examples\/Multi@.@@ -24,17 +24,17 @@ , module Data.Comp.Multi.Generic ) where -import Data.Comp.Multi.HFunctor-import Data.Comp.Multi.Term import Data.Comp.Multi.Algebra-import Data.Comp.Multi.Sum import Data.Comp.Multi.Annotation import Data.Comp.Multi.Equality import Data.Comp.Multi.Generic+import Data.Comp.Multi.HFunctor+import Data.Comp.Multi.Sum+import Data.Comp.Multi.Term {- $ex1-The example illustrates how to use generalised compositional data types -to implement a small expression language, with a sub language of values, and +The example illustrates how to use generalised compositional data types+to implement a small expression language, with a sub language of values, and an evaluation function mapping expressions to values. The following language extensions are needed in order to run the example:@@ -45,7 +45,7 @@ > import Data.Comp.Multi > import Data.Comp.Multi.Show () > import Data.Comp.Multi.Derive-> +> > -- Signature for values and operators > data Value e l where > Const :: Int -> Value e Int@@ -54,41 +54,41 @@ > Add, Mult :: e Int -> e Int -> Op e Int > Fst :: e (s,t) -> Op e s > Snd :: e (s,t) -> Op e t-> +> > -- Signature for the simple expression language > type Sig = Op :+: Value-> +> > -- Derive boilerplate code using Template Haskell (GHC 7 needed)-> $(derive [makeHFunctor, makeHShowF, makeHEqF, smartConstructors] +> $(derive [makeHFunctor, makeHShowF, makeHEqF, smartConstructors] > [''Value, ''Op])-> +> > -- Term evaluation algebra > class Eval f v where > evalAlg :: Alg f (Term v)-> +> > instance (Eval f v, Eval g v) => Eval (f :+: g) v where > evalAlg (Inl x) = evalAlg x > evalAlg (Inr x) = evalAlg x-> +> > -- Lift the evaluation algebra to a catamorphism > eval :: (HFunctor f, Eval f v) => Term f :-> Term v > eval = cata evalAlg-> +> > instance (Value :<: v) => Eval Value v where > evalAlg = inject-> +> > instance (Value :<: v) => Eval Op v where > evalAlg (Add x y) = iConst $ (projC x) + (projC y) > evalAlg (Mult x y) = iConst $ (projC x) * (projC y) > evalAlg (Fst x) = fst $ projP x > evalAlg (Snd x) = snd $ projP x-> +> > projC :: (Value :<: v) => Term v Int -> Int > projC v = case project v of Just (Const n) -> n-> +> > projP :: (Value :<: v) => Term v (s,t) -> (Term v s, Term v t) > projP v = case project v of Just (Pair x y) -> (x,y)-> +> > -- Example: evalEx = iConst 2 > evalEx :: Term Value Int > evalEx = eval (iFst $ iPair (iConst 2) (iConst 1) :: Term Sig Int)@@ -96,7 +96,7 @@ {- $ex2 The example illustrates how to use generalised compositional data types to-implement a small expression language, with a sub language of values, and a +implement a small expression language, with a sub language of values, and a monadic evaluation function mapping expressions to values. The following language extensions are needed in order to run the example:@@ -108,7 +108,7 @@ > import Data.Comp.Multi.Show () > import Data.Comp.Multi.Derive > import Control.Monad (liftM)-> +> > -- Signature for values and operators > data Value e l where > Const :: Int -> Value e Int@@ -117,29 +117,29 @@ > Add, Mult :: e Int -> e Int -> Op e Int > Fst :: e (s,t) -> Op e s > Snd :: e (s,t) -> Op e t-> +> > -- Signature for the simple expression language > type Sig = Op :+: Value-> +> > -- Derive boilerplate code using Template Haskell (GHC 7 needed) > $(derive [makeHFunctor, makeHTraversable, makeHFoldable, > makeHEqF, makeHShowF, smartConstructors] > [''Value, ''Op])-> +> > -- Monadic term evaluation algebra > class EvalM f v where > evalAlgM :: AlgM Maybe f (Term v)-> +> > instance (EvalM f v, EvalM g v) => EvalM (f :+: g) v where > evalAlgM (Inl x) = evalAlgM x > evalAlgM (Inr x) = evalAlgM x-> +> > evalM :: (HTraversable f, EvalM f v) => Term f l -> Maybe (Term v l) > evalM = cataM evalAlgM-> +> > instance (Value :<: v) => EvalM Value v where > evalAlgM = return . inject-> +> > instance (Value :<: v) => EvalM Op v where > evalAlgM (Add x y) = do n1 <- projC x > n2 <- projC y@@ -149,15 +149,15 @@ > return $ iConst $ n1 * n2 > evalAlgM (Fst v) = liftM fst $ projP v > evalAlgM (Snd v) = liftM snd $ projP v-> +> > projC :: (Value :<: v) => Term v Int -> Maybe Int > projC v = case project v of > Just (Const n) -> return n; _ -> Nothing-> +> > projP :: (Value :<: v) => Term v (a,b) -> Maybe (Term v a, Term v b) > projP v = case project v of > Just (Pair x y) -> return (x,y); _ -> Nothing-> +> > -- Example: evalMEx = Just (iConst 5) > evalMEx :: Maybe (Term Value Int) > evalMEx = evalM ((iConst 1) `iAdd`@@ -165,7 +165,7 @@ -} {- $ex3-The example illustrates how to use generalised compositional data types +The example illustrates how to use generalised compositional data types to implement a small expression language, and an evaluation function mapping intrinsically typed expressions to values. @@ -177,7 +177,7 @@ > import Data.Comp.Multi > import Data.Comp.Multi.Show () > import Data.Comp.Multi.Derive-> +> > -- Signature for values and operators > data Value e l where > Const :: Int -> Value e Int@@ -186,36 +186,36 @@ > Add, Mult :: e Int -> e Int -> Op e Int > Fst :: e (s,t) -> Op e s > Snd :: e (s,t) -> Op e t-> +> > -- Signature for the simple expression language > type Sig = Op :+: Value-> +> > -- Derive boilerplate code using Template Haskell (GHC 7 needed)-> $(derive [makeHFunctor, makeHShowF, makeHEqF, smartConstructors] +> $(derive [makeHFunctor, makeHShowF, makeHEqF, smartConstructors] > [''Value, ''Op])-> +> > -- Term evaluation algebra > class EvalI f where > evalAlgI :: Alg f I-> +> > instance (EvalI f, EvalI g) => EvalI (f :+: g) where > evalAlgI (Inl x) = evalAlgI x > evalAlgI (Inr x) = evalAlgI x-> +> > -- Lift the evaluation algebra to a catamorphism > evalI :: (HFunctor f, EvalI f) => Term f i -> i > evalI = unI . cata evalAlgI-> +> > instance EvalI Value where > evalAlgI (Const n) = I n > evalAlgI (Pair (I x) (I y)) = I (x,y)-> +> > instance EvalI Op where > evalAlgI (Add (I x) (I y)) = I (x + y) > evalAlgI (Mult (I x) (I y)) = I (x * y) > evalAlgI (Fst (I (x,_))) = I x > evalAlgI (Snd (I (_,y))) = I y-> +> > -- Example: evalEx = 2 > evalIEx :: Int > evalIEx = evalI (iFst $ iPair (iConst 2) (iConst 1) :: Term Sig Int)@@ -233,7 +233,7 @@ > import Data.Comp.Multi > import Data.Comp.Multi.Show () > import Data.Comp.Multi.Derive-> +> > -- Signature for values, operators, and syntactic sugar > data Value e l where > Const :: Int -> Value e Int@@ -245,75 +245,75 @@ > data Sugar e l where > Neg :: e Int -> Sugar e Int > Swap :: e (s,t) -> Sugar e (t,s)-> +> > -- Source position information (line number, column number) > data Pos = Pos Int Int > deriving Show-> +> > -- Signature for the simple expression language > type Sig = Op :+: Value > type SigP = Op :&: Pos :+: Value :&: Pos-> +> > -- Signature for the simple expression language, extended with syntactic sugar > type Sig' = Sugar :+: Op :+: Value > type SigP' = Sugar :&: Pos :+: Op :&: Pos :+: Value :&: Pos-> +> > -- Derive boilerplate code using Template Haskell (GHC 7 needed) > $(derive [makeHFunctor, makeHTraversable, makeHFoldable, > makeHEqF, makeHShowF, smartConstructors] > [''Value, ''Op, ''Sugar])-> +> > -- Term homomorphism for desugaring of terms > class (HFunctor f, HFunctor g) => Desugar f g where > desugHom :: Hom f g > desugHom = desugHom' . hfmap Hole > desugHom' :: Alg f (Context g a) > desugHom' x = appCxt (desugHom x)-> +> > instance (Desugar f h, Desugar g h) => Desugar (f :+: g) h where > desugHom (Inl x) = desugHom x > desugHom (Inr x) = desugHom x > desugHom' (Inl x) = desugHom' x > desugHom' (Inr x) = desugHom' x-> +> > instance (Value :<: v, HFunctor v) => Desugar Value v where > desugHom = simpCxt . inj-> +> > instance (Op :<: v, HFunctor v) => Desugar Op v where > desugHom = simpCxt . inj-> +> > instance (Op :<: v, Value :<: v, HFunctor v) => Desugar Sugar v where > desugHom' (Neg x) = iConst (-1) `iMult` x > desugHom' (Swap x) = iSnd x `iPair` iFst x-> +> > -- Term evaluation algebra > class Eval f v where > evalAlg :: Alg f (Term v)-> +> > instance (Eval f v, Eval g v) => Eval (f :+: g) v where > evalAlg (Inl x) = evalAlg x > evalAlg (Inr x) = evalAlg x-> +> > instance (Value :<: v) => Eval Value v where > evalAlg = inject-> +> > instance (Value :<: v) => Eval Op v where > evalAlg (Add x y) = iConst $ (projC x) + (projC y) > evalAlg (Mult x y) = iConst $ (projC x) * (projC y) > evalAlg (Fst x) = fst $ projP x > evalAlg (Snd x) = snd $ projP x-> +> > projC :: (Value :<: v) => Term v Int -> Int > projC v = case project v of Just (Const n) -> n-> +> > projP :: (Value :<: v) => Term v (s,t) -> (Term v s, Term v t) > projP v = case project v of Just (Pair x y) -> (x,y)-> +> > -- Compose the evaluation algebra and the desugaring homomorphism to an > -- algebra > eval :: Term Sig' :-> Term Value > eval = cata (evalAlg `compAlg` (desugHom :: Hom Sig' Sig))-> +> > -- Example: evalEx = iPair (iConst 2) (iConst 1) > evalEx :: Term Value (Int,Int) > evalEx = eval $ iSwap $ iPair (iConst 1) (iConst 2)@@ -332,7 +332,7 @@ > import Data.Comp.Multi > import Data.Comp.Multi.Show () > import Data.Comp.Multi.Derive-> +> > -- Signature for values, operators, and syntactic sugar > data Value e l where > Const :: Int -> Value e Int@@ -344,74 +344,74 @@ > data Sugar e l where > Neg :: e Int -> Sugar e Int > Swap :: e (s,t) -> Sugar e (t,s)-> +> > -- Source position information (line number, column number) > data Pos = Pos Int Int > deriving (Show, Eq)-> +> > -- Signature for the simple expression language > type Sig = Op :+: Value > type SigP = Op :&: Pos :+: Value :&: Pos-> +> > -- Signature for the simple expression language, extended with syntactic sugar > type Sig' = Sugar :+: Op :+: Value > type SigP' = Sugar :&: Pos :+: Op :&: Pos :+: Value :&: Pos-> +> > -- Derive boilerplate code using Template Haskell (GHC 7 needed) > $(derive [makeHFunctor, makeHTraversable, makeHFoldable, > makeHEqF, makeHShowF, smartConstructors] > [''Value, ''Op, ''Sugar])-> +> > -- Term homomorphism for desugaring of terms > class (HFunctor f, HFunctor g) => Desugar f g where > desugHom :: Hom f g > desugHom = desugHom' . hfmap Hole > desugHom' :: Alg f (Context g a) > desugHom' x = appCxt (desugHom x)-> +> > instance (Desugar f h, Desugar g h) => Desugar (f :+: g) h where > desugHom (Inl x) = desugHom x > desugHom (Inr x) = desugHom x > desugHom' (Inl x) = desugHom' x > desugHom' (Inr x) = desugHom' x-> +> > instance (Value :<: v, HFunctor v) => Desugar Value v where > desugHom = simpCxt . inj-> +> > instance (Op :<: v, HFunctor v) => Desugar Op v where > desugHom = simpCxt . inj-> +> > instance (Op :<: v, Value :<: v, HFunctor v) => Desugar Sugar v where > desugHom' (Neg x) = iConst (-1) `iMult` x > desugHom' (Swap x) = iSnd x `iPair` iFst x-> +> > -- Lift the desugaring term homomorphism to a catamorphism > desug :: Term Sig' :-> Term Sig > desug = appHom desugHom-> +> > -- Example: desugEx = iPair (iConst 2) (iConst 1) > desugEx :: Term Sig (Int,Int) > desugEx = desug $ iSwap $ iPair (iConst 1) (iConst 2)-> +> > -- Lift desugaring to terms annotated with source positions > desugP :: Term SigP' :-> Term SigP > desugP = appHom (propAnn desugHom)-> +> > iSwapP :: (DistAnn f p f', Sugar :<: f) => p -> Term f' (a,b) -> Term f' (b,a) > iSwapP p x = Term (injectA p $ inj $ Swap x)-> +> > iConstP :: (DistAnn f p f', Value :<: f) => p -> Int -> Term f' Int > iConstP p x = Term (injectA p $ inj $ Const x)-> +> > iPairP :: (DistAnn f p f', Value :<: f) => p -> Term f' a -> Term f' b -> Term f' (a,b) > iPairP p x y = Term (injectA p $ inj $ Pair x y)-> +> > iFstP :: (DistAnn f p f', Op :<: f) => p -> Term f' (a,b) -> Term f' a > iFstP p x = Term (injectA p $ inj $ Fst x)-> +> > iSndP :: (DistAnn f p f', Op :<: f) => p -> Term f' (a,b) -> Term f' b > iSndP p x = Term (injectA p $ inj $ Snd x)-> +> > -- Example: desugPEx = iPairP (Pos 1 0) > -- (iSndP (Pos 1 0) (iPairP (Pos 1 1) > -- (iConstP (Pos 1 2) 1)
src/Data/Comp/Multi/Algebra.hs view
@@ -1,5 +1,9 @@-{-# LANGUAGE GADTs, Rank2Types, TypeOperators, ScopedTypeVariables, - FlexibleContexts, KindSignatures #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE GADTs #-}+{-# LANGUAGE KindSignatures #-}+{-# LANGUAGE Rank2Types #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeOperators #-} -------------------------------------------------------------------------------- -- | -- Module : Data.Comp.Multi.Algebra@@ -22,7 +26,7 @@ cata, cata', appCxt,- + -- * Monadic Algebras & Catamorphisms AlgM, freeM,@@ -86,11 +90,13 @@ ) where -import Data.Comp.Multi.Term+import Control.Monad+import Data.Kind+ import Data.Comp.Multi.HFunctor import Data.Comp.Multi.HTraversable+import Data.Comp.Multi.Term import Data.Comp.Ops-import Control.Monad -- | This type represents multisorted @f@-algebras with a family @e@ -- of carriers.@@ -107,7 +113,7 @@ -- | Construct a catamorphism from the given algebra. cata :: forall f a. HFunctor f => Alg f a -> Term f :-> a-cata f = run +cata f = run where run :: Term f :-> a run (Term t) = f (hfmap run t) @@ -160,7 +166,7 @@ -- | This type represents uniform signature function specification.-type SigFun f g = forall (a :: * -> *). f a :-> g a+type SigFun f g = forall (a :: Type -> Type). f a :-> g a -- | This type represents context function. type CxtFun f g = forall h . SigFun (Cxt h f) (Cxt h g)@@ -225,7 +231,7 @@ hom f = simpCxt . f -- | This type represents monadic signature functions.-type SigFunM m f g = forall (a :: * -> *) . NatM m (f a) (g a)+type SigFunM m f g = forall (a :: Type -> Type) . NatM m (f a) (g a) -- | This type represents monadic context function.@@ -342,7 +348,7 @@ anaM :: forall a m f. (HTraversable f, Monad m) => CoalgM m f a -> NatM m a (Term f)-anaM f = run +anaM f = run where run :: NatM m a (Term f) run t = liftM Term $ f t >>= hmapM run @@ -367,7 +373,7 @@ -- | This function constructs a monadic paramorphism from the given -- monadic r-algebra-paraM :: forall f m a. (HTraversable f, Monad m) => +paraM :: forall f m a. (HTraversable f, Monad m) => RAlgM m f a -> NatM m(Term f) a paraM f = liftM fsnd . cataM run where run :: AlgM m f (Term f :*: a)@@ -386,7 +392,7 @@ -- | This function constructs an apomorphism from the given -- r-coalgebra. apo :: forall f a . (HFunctor f) => RCoalg f a -> a :-> Term f-apo f = run +apo f = run where run :: a :-> Term f run = Term . hfmap run' . f run' :: Term f :+: a :-> Term f@@ -402,7 +408,7 @@ -- monadic r-coalgebra. apoM :: forall f m a . (HTraversable f, Monad m) => RCoalgM m f a -> NatM m a (Term f)-apoM f = run +apoM f = run where run :: NatM m a (Term f) run a = do t <- f a
src/Data/Comp/Multi/Annotation.hs view
@@ -1,5 +1,12 @@-{-# LANGUAGE TypeOperators, MultiParamTypeClasses,- FlexibleInstances, UndecidableInstances, Rank2Types, GADTs, ScopedTypeVariables #-}+{-# LANGUAGE ConstraintKinds #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE GADTs #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE Rank2Types #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeOperators #-}+{-# LANGUAGE UndecidableInstances #-} -------------------------------------------------------------------------------- -- | -- Module : Data.Comp.Multi.Annotation@@ -27,14 +34,11 @@ project' ) where -import Data.Comp.Multi.Term-import Data.Comp.Multi.Sum-import Data.Comp.Multi.Ops-import qualified Data.Comp.Ops as O import Data.Comp.Multi.Algebra import Data.Comp.Multi.HFunctor--import Control.Monad+import Data.Comp.Multi.Ops+import Data.Comp.Multi.Term+import qualified Data.Comp.Ops as O -- | This function transforms a function with a domain constructed -- from a functor to a function with a domain constructed with the@@ -56,7 +60,7 @@ => (s' a :-> Cxt h s' a) -> s a :-> Cxt h s a liftA' f v = let (v' O.:&: p) = projectA v in ann p (f v')- + {-| This function strips the annotations from a term over a functor with annotations. -} @@ -64,12 +68,13 @@ stripA = appSigFun remA -propAnn :: (DistAnn f p f', DistAnn g p g', HFunctor g) +propAnn :: (DistAnn f p f', DistAnn g p g', HFunctor g) => Hom f g -> Hom f' g' propAnn alg f' = ann p (alg f) where (f O.:&: p) = projectA f' -- | This function is similar to 'project' but applies to signatures -- with an annotation which is then ignored.-project' :: forall s s' f h a i . (RemA s s', s :<: f) => Cxt h f a i -> Maybe (s' (Cxt h f a) i)-project' v = liftM remA (project v :: Maybe (s (Cxt h f a) i))+project' :: (RemA f f', s :<: f') => Cxt h f a i -> Maybe (s (Cxt h f a) i)+project' (Term x) = proj $ remA x+project' _ = Nothing
src/Data/Comp/Multi/Derive.hs view
@@ -42,13 +42,13 @@ import Data.Comp.Derive.Utils (derive, liftSumGen) import Data.Comp.Multi.Derive.Equality-import Data.Comp.Multi.Derive.Ordering-import Data.Comp.Multi.Derive.Show-import Data.Comp.Multi.Derive.HFunctor import Data.Comp.Multi.Derive.HFoldable+import Data.Comp.Multi.Derive.HFunctor import Data.Comp.Multi.Derive.HTraversable-import Data.Comp.Multi.Derive.SmartConstructors+import Data.Comp.Multi.Derive.Ordering+import Data.Comp.Multi.Derive.Show import Data.Comp.Multi.Derive.SmartAConstructors+import Data.Comp.Multi.Derive.SmartConstructors import Data.Comp.Multi.Ops ((:+:), caseH) import Language.Haskell.TH
src/Data/Comp/Multi/Derive/Equality.hs view
@@ -1,4 +1,5 @@-{-# LANGUAGE TemplateHaskell, FlexibleInstances, IncoherentInstances #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE TemplateHaskell #-} -------------------------------------------------------------------------------- -- | -- Module : Data.Comp.Multi.Derive.Equality@@ -26,36 +27,35 @@ kind taking at least two arguments. -} makeEqHF :: Name -> Q [Dec] makeEqHF fname = do- TyConI (DataD _cxt name args constrs _deriving) <- abstractNewtypeQ $ reify fname+ Just (DataInfo _cxt name args constrs _deriving) <- abstractNewtypeQ $ reify fname let args' = init args argNames = map (VarT . tyVarBndrName) (init args') ftyp = VarT . tyVarBndrName $ last args' complType = foldl AppT (ConT name) argNames- preCond = map (ClassP ''Eq . (: [])) argNames+ preCond = map (mkClassP ''Eq . (: [])) argNames classType = AppT (ConT ''EqHF) complType constrs' <- mapM normalConExp constrs eqFDecl <- funD 'eqHF (eqFClauses ftyp constrs constrs')- return [InstanceD preCond classType [eqFDecl]]+ return [mkInstanceD preCond classType [eqFDecl]] where eqFClauses ftyp constrs constrs' = map (genEqClause ftyp) constrs' ++ defEqClause constrs- filterFarg fArg ty x = (containsType ty fArg, varE x) defEqClause constrs | length constrs < 2 = [] | otherwise = [clause [wildP,wildP] (normalB [|False|]) []]- genEqClause ftyp (constr, argts) = do + genEqClause ftyp (constr, argts, gadtTy) = do let n = length argts varNs <- newNames n "x" varNs' <- newNames n "y"- let pat = ConP constr $ map VarP varNs- pat' = ConP constr $ map VarP varNs'+ let pat = ConP constr [] $ map VarP varNs+ pat' = ConP constr [] $ map VarP varNs' vars = map VarE varNs vars' = map VarE varNs' mkEq ty x y = let (x',y') = (return x,return y)- in if containsType ty ftyp+ in if containsType ty (getBinaryFArg ftyp gadtTy) then [| $x' `keq` $y'|] else [| $x' == $y'|] eqs = listE $ zipWith3 mkEq argts vars vars'- body <- if n == 0 + body <- if n == 0 then [|True|] else [|and $eqs|] return $ Clause [pat, pat'] (NormalB body) []
src/Data/Comp/Multi/Derive/HFoldable.hs view
@@ -18,25 +18,24 @@ makeHFoldable )where +import Control.Monad import Data.Comp.Derive.Utils-import Data.Comp.Multi.HFunctor import Data.Comp.Multi.HFoldable+import Data.Comp.Multi.HFunctor import Data.Foldable-import Language.Haskell.TH-import Data.Monoid import Data.Maybe-import qualified Prelude as P (foldl,foldr,foldl1)-import Prelude hiding (foldl,foldr,foldl1)-import Control.Monad+import Data.Monoid+import Language.Haskell.TH+import Prelude hiding (foldl, foldl1, foldr)+import qualified Prelude as P (foldl, foldl1, foldr) iter 0 _ e = e iter n f e = iter (n-1) f (f `appE` e) -iter' n f e = run n f e- where run 0 _ e = e- run m f e = let f' = iter (m-1) [|fmap|] f- in run (m-1) f (f' `appE` e)+iter' 0 _ e = e+iter' m f e = let f' = iter (m-1) [|fmap|] f+ in iter' (m-1) f (f' `appE` e) iterSp n f g e = run n e where run 0 e = e@@ -47,7 +46,7 @@ kind taking at least two arguments. -} makeHFoldable :: Name -> Q [Dec] makeHFoldable fname = do- TyConI (DataD _cxt name args constrs _deriving) <- abstractNewtypeQ $ reify fname+ Just (DataInfo _cxt name args constrs _deriving) <- abstractNewtypeQ $ reify fname let args' = init args fArg = VarT . tyVarBndrName $ last args' argNames = map (VarT . tyVarBndrName) (init args')@@ -58,13 +57,13 @@ foldMapDecl <- funD 'hfoldMap (map foldMapClause constrs') foldlDecl <- funD 'hfoldl (map foldlClause constrs') foldrDecl <- funD 'hfoldr (map foldrClause constrs')- return [InstanceD [] classType [foldDecl,foldMapDecl,foldlDecl,foldrDecl]]- where isFarg fArg (constr, args) = (constr, map (`containsType'` fArg) args)+ return [mkInstanceD [] classType [foldDecl,foldMapDecl,foldlDecl,foldrDecl]]+ where isFarg fArg (constr, args, gadtTy) = (constr, map (`containsType'` (getBinaryFArg fArg gadtTy)) args) filterVar [] _ = Nothing filterVar [d] x =Just (d, varE x) filterVar _ _ = error "functor variable occurring twice in argument type" filterVars args varNs = catMaybes $ zipWith filterVar args varNs- mkCPat constr args varNs = ConP constr $ zipWith mkPat args varNs+ mkCPat constr args varNs = ConP constr [] $ zipWith mkPat args varNs mkPat [] _ = WildP mkPat _ x = VarP x mkPatAndVars (constr, args) =@@ -86,7 +85,7 @@ fp = if null vars then WildP else VarP fn body <- case vars of [] -> [|mempty|]- (_:_) -> P.foldl1 (\ x y -> [|$x `mappend` $y|]) $ + (_:_) -> P.foldl1 (\ x y -> [|$x `mappend` $y|]) $ map (\ (d,z) -> iter' (max (d-1) 0) [|fold|] (f' d `appE` z)) vars return $ Clause [fp, pat] (NormalB body) [] foldlClause (pat,vars) =
src/Data/Comp/Multi/Derive/HFunctor.hs view
@@ -18,13 +18,13 @@ makeHFunctor ) where +import Control.Monad import Data.Comp.Derive.Utils import Data.Comp.Multi.HFunctor+import Data.Maybe import Language.Haskell.TH-import qualified Prelude as P (mapM) import Prelude hiding (mapM)-import Data.Maybe-import Control.Monad+import qualified Prelude as P (mapM) iter 0 _ e = e iter n f e = iter (n-1) f (f `appE` e)@@ -33,7 +33,7 @@ kind taking at least two arguments. -} makeHFunctor :: Name -> Q [Dec] makeHFunctor fname = do- TyConI (DataD _cxt name args constrs _deriving) <- abstractNewtypeQ $ reify fname+ Just (DataInfo _cxt name args constrs _deriving) <- abstractNewtypeQ $ reify fname let args' = init args fArg = VarT . tyVarBndrName $ last args' argNames = map (VarT . tyVarBndrName) (init args')@@ -41,14 +41,15 @@ classType = AppT (ConT ''HFunctor) complType constrs' <- P.mapM (mkPatAndVars . isFarg fArg <=< normalConExp) constrs hfmapDecl <- funD 'hfmap (map hfmapClause constrs')- return [InstanceD [] classType [hfmapDecl]]- where isFarg fArg (constr, args) = (constr, map (`containsType'` fArg) args)+ return [mkInstanceD [] classType [hfmapDecl]]+ where isFarg fArg (constr, args, ty) = (constr, map (`containsType'` getBinaryFArg fArg ty) args) filterVar _ nonFarg [] x = nonFarg x filterVar farg _ [depth] x = farg depth x filterVar _ _ _ _ = error "functor variable occurring twice in argument type" filterVars args varNs farg nonFarg = zipWith (filterVar farg nonFarg) args varNs- mkCPat constr varNs = ConP constr $ map mkPat varNs+ mkCPat constr varNs = ConP constr [] $ map mkPat varNs mkPat = VarP+ mkPatAndVars :: (Name, [[t]]) -> Q (Q Exp, Pat, (t -> Q Exp -> c) -> (Q Exp -> c) -> [c], Bool, [Q Exp], [(t, Name)]) mkPatAndVars (constr, args) = do varNs <- newNames (length args) "x" return (conE constr, mkCPat constr varNs,
src/Data/Comp/Multi/Derive/HTraversable.hs view
@@ -18,30 +18,26 @@ makeHTraversable ) where +import Control.Applicative+import Control.Monad hiding (mapM, sequence) import Data.Comp.Derive.Utils import Data.Comp.Multi.HTraversable-import Language.Haskell.TH+import Data.Foldable hiding (any, or) import Data.Maybe import Data.Traversable-import Data.Foldable hiding (any,or)-import Control.Applicative-import Control.Monad hiding (mapM, sequence)+import Language.Haskell.TH+import Prelude hiding (foldl, foldr, mapM, sequence) import qualified Prelude as P (foldl, foldr, mapM)-import Prelude hiding (foldl, foldr,mapM, sequence) iter 0 _ e = e iter n f e = iter (n-1) f (f `appE` e) -iter' n f e = run n f e- where run 0 _ e = e- run m f e = let f' = iter (m-1) [|fmap|] f- in run (m-1) f (f' `appE` e) {-| Derive an instance of 'HTraversable' for a type constructor of any higher-order kind taking at least two arguments. -} makeHTraversable :: Name -> Q [Dec] makeHTraversable fname = do- TyConI (DataD _cxt name args constrs _deriving) <- abstractNewtypeQ $ reify fname+ Just (DataInfo _cxt name args constrs _deriving) <- abstractNewtypeQ $ reify fname let args' = init args fArg = VarT . tyVarBndrName $ last args' argNames = map (VarT . tyVarBndrName) (init args')@@ -50,13 +46,13 @@ constrs' <- P.mapM (mkPatAndVars . isFarg fArg <=< normalConExp) constrs traverseDecl <- funD 'htraverse (map traverseClause constrs') mapMDecl <- funD 'hmapM (map mapMClause constrs')- return [InstanceD [] classType [traverseDecl, mapMDecl]]- where isFarg fArg (constr, args) = (constr, map (`containsType'` fArg) args)+ return [mkInstanceD [] classType [traverseDecl, mapMDecl]]+ where isFarg fArg (constr, args, gadtTy) = (constr, map (`containsType'` (getBinaryFArg fArg gadtTy)) args) filterVar _ nonFarg [] x = nonFarg x filterVar farg _ [depth] x = farg depth x filterVar _ _ _ _ = error "functor variable occurring twice in argument type" filterVars args varNs farg nonFarg = zipWith (filterVar farg nonFarg) args varNs- mkCPat constr varNs = ConP constr $ map mkPat varNs+ mkCPat constr varNs = ConP constr [] $ map mkPat varNs mkPat = VarP mkPatAndVars (constr, args) = do varNs <- newNames (length args) "x"
− src/Data/Comp/Multi/Derive/Injections.hs
@@ -1,87 +0,0 @@-{-# LANGUAGE TemplateHaskell #-}------------------------------------------------------------------------------------ |--- Module : Data.Comp.Multi.Derive.Injections--- Copyright : (c) 2011 Patrick Bahr, Tom Hvitved--- License : BSD3--- Maintainer : Tom Hvitved <hvitved@diku.dk>--- Stability : experimental--- Portability : non-portable (GHC Extensions)------ Derive functions for signature injections.--------------------------------------------------------------------------------------module Data.Comp.Multi.Derive.Injections- (- injn,- injectn,- deepInjectn- ) where--import Language.Haskell.TH hiding (Cxt)-import Data.Comp.Multi.HFunctor-import Data.Comp.Multi.Term-import Data.Comp.Multi.Algebra (CxtFun, appSigFun)-import Data.Comp.Multi.Ops ((:+:)(..), (:<:)(..))--injn :: Int -> Q [Dec]-injn n = do- let i = mkName $ "inj" ++ show n- let fvars = map (\n -> mkName $ 'f' : show n) [1..n]- let gvar = mkName "g"- let avar = mkName "a"- let ivar = mkName "i"- let xvar = mkName "x"- let d = [funD i [clause [varP xvar] (normalB $ genDecl xvar n) []]]- sequence $ sigD i (genSig fvars gvar avar ivar) : d- where genSig fvars gvar avar ivar = do- let cxt = map (\f -> classP ''(:<:) [varT f, varT gvar]) fvars- let tp = foldl1 (\a f -> conT ''(:+:) `appT` f `appT` a)- (map varT fvars)- let tp' = arrowT `appT` (tp `appT` varT avar `appT` varT ivar)- `appT` (varT gvar `appT` varT avar- `appT` varT ivar)- forallT (map PlainTV $ gvar : avar : ivar : fvars)- (sequence cxt) tp'- genDecl x n = [| case $(varE x) of- Inl x -> $(varE $ mkName "inj") x- Inr x -> $(varE $ mkName $ "inj" ++- if n > 2 then show (n - 1) else "") x |]-injectn :: Int -> Q [Dec]-injectn n = do- let i = mkName ("inject" ++ show n)- let fvars = map (\n -> mkName $ 'f' : show n) [1..n]- let gvar = mkName "g"- let avar = mkName "a"- let ivar = mkName "i"- let d = [funD i [clause [] (normalB $ genDecl n) []]]- sequence $ sigD i (genSig fvars gvar avar ivar) : d- where genSig fvars gvar avar ivar = do- let hvar = mkName "h"- let cxt = map (\f -> classP ''(:<:) [varT f, varT gvar]) fvars- let tp = foldl1 (\a f -> conT ''(:+:) `appT` f `appT` a)- (map varT fvars)- let tp' = conT ''Cxt `appT` varT hvar `appT` varT gvar- `appT` varT avar- let tp'' = arrowT `appT` (tp `appT` tp' `appT` varT ivar)- `appT` (tp' `appT` varT ivar)- forallT (map PlainTV $ hvar : gvar : avar : ivar : fvars)- (sequence cxt) tp''- genDecl n = [| Term . $(varE $ mkName $ "inj" ++ show n) |]--deepInjectn :: Int -> Q [Dec]-deepInjectn n = do- let i = mkName ("deepInject" ++ show n)- let fvars = map (\n -> mkName $ 'f' : show n) [1..n]- let gvar = mkName "g"- let d = [funD i [clause [] (normalB $ genDecl n) []]]- sequence $ sigD i (genSig fvars gvar) : d- where genSig fvars gvar = do- let cxt = map (\f -> classP ''(:<:) [varT f, varT gvar]) fvars- let tp = foldl1 (\a f -> conT ''(:+:) `appT` f `appT` a)- (map varT fvars)- let cxt' = classP ''HFunctor [tp]- let tp' = conT ''CxtFun `appT` tp `appT` varT gvar- forallT (map PlainTV $ gvar : fvars) (sequence $ cxt' : cxt) tp'- genDecl n = [| appSigFun $(varE $ mkName $ "inj" ++ show n) |]
src/Data/Comp/Multi/Derive/Ordering.hs view
@@ -1,5 +1,6 @@-{-# LANGUAGE TemplateHaskell, FlexibleInstances, IncoherentInstances,- ScopedTypeVariables #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TemplateHaskell #-} -------------------------------------------------------------------------------- -- | -- Module : Data.Comp.Multi.Derive.Ordering@@ -18,10 +19,10 @@ makeOrdHF ) where -import Data.Comp.Multi.Ordering import Data.Comp.Derive.Utils-import Data.Maybe+import Data.Comp.Multi.Ordering import Data.List+import Data.Maybe import Language.Haskell.TH hiding (Cxt) compList :: [Ordering] -> Ordering@@ -31,19 +32,19 @@ kind taking at least three arguments. -} makeOrdHF :: Name -> Q [Dec] makeOrdHF fname = do- TyConI (DataD _ name args constrs _) <- abstractNewtypeQ $ reify fname+ Just (DataInfo _ name args constrs _) <- abstractNewtypeQ $ reify fname let args' = init args -- covariant argument- let coArg :: Name = tyVarBndrName $ last args'+ let coArg :: Type = VarT $ tyVarBndrName $ last args' let argNames = map (VarT . tyVarBndrName) (init args') let complType = foldl AppT (ConT name) argNames let classType = AppT (ConT ''OrdHF) complType- constrs' :: [(Name,[Type])] <- mapM normalConExp constrs+ constrs' :: [(Name,[Type],Maybe Type)] <- mapM normalConExp constrs compareHFDecl <- funD 'compareHF (compareHFClauses coArg constrs')- return [InstanceD [] classType [compareHFDecl]]- where compareHFClauses :: Name -> [(Name,[Type])] -> [ClauseQ]+ return [mkInstanceD [] classType [compareHFDecl]]+ where compareHFClauses :: Type -> [(Name,[Type],Maybe Type)] -> [ClauseQ] compareHFClauses _ [] = []- compareHFClauses coArg constrs = + compareHFClauses coArg constrs = let constrs' = constrs `zip` [1..] constPairs = [(x,y)| x<-constrs', y <- constrs'] in map (genClause coArg) constPairs@@ -51,24 +52,24 @@ | n == m = genEqClause coArg c | n < m = genLtClause c d | otherwise = genGtClause c d- genEqClause :: Name -> (Name,[Type]) -> ClauseQ- genEqClause coArg (constr, args) = do + genEqClause :: Type -> (Name,[Type],Maybe Type) -> ClauseQ+ genEqClause coArg (constr, args,gadtTy) = do varXs <- newNames (length args) "x" varYs <- newNames (length args) "y"- let patX = ConP constr $ map VarP varXs- let patY = ConP constr $ map VarP varYs- body <- eqDBody coArg (zip3 varXs varYs args)+ let patX = ConP constr [] $ map VarP varXs+ let patY = ConP constr [] $ map VarP varYs+ body <- eqDBody (getBinaryFArg coArg gadtTy) (zip3 varXs varYs args) return $ Clause [patX, patY] (NormalB body) []- eqDBody :: Name -> [(Name, Name, Type)] -> ExpQ+ eqDBody :: Type -> [(Name, Name, Type)] -> ExpQ eqDBody coArg x = [|compList $(listE $ map (eqDB coArg) x)|]- eqDB :: Name -> (Name, Name, Type) -> ExpQ+ eqDB :: Type -> (Name, Name, Type) -> ExpQ eqDB coArg (x, y, tp)- | not (containsType tp (VarT coArg)) =+ | not (containsType tp coArg) = [| compare $(varE x) $(varE y) |] | otherwise = [| kcompare $(varE x) $(varE y) |]- genLtClause (c, _) (d, _) =+ genLtClause (c, _, _) (d, _, _) = clause [recP c [], recP d []] (normalB [| LT |]) []- genGtClause (c, _) (d, _) =+ genGtClause (c, _, _) (d, _, _) = clause [recP c [], recP d []] (normalB [| GT |]) []
− src/Data/Comp/Multi/Derive/Projections.hs
@@ -1,100 +0,0 @@-{-# LANGUAGE TemplateHaskell, GADTs #-}------------------------------------------------------------------------------------ |--- Module : Data.Comp.Multi.Derive.Projections--- Copyright : (c) 2011 Patrick Bahr, Tom Hvitved--- License : BSD3--- Maintainer : Tom Hvitved <hvitved@diku.dk>--- Stability : experimental--- Portability : non-portable (GHC Extensions)------ Derive functions for signature projections.--------------------------------------------------------------------------------------module Data.Comp.Multi.Derive.Projections- (- projn,- projectn,- deepProjectn- ) where--import Language.Haskell.TH hiding (Cxt)-import Control.Monad (liftM)-import Data.Comp.Multi.HTraversable (HTraversable)-import Data.Comp.Multi.Term-import Data.Comp.Multi.Algebra (CxtFunM, appSigFunM')-import Data.Comp.Multi.Ops ((:+:)(..), (:<:)(..))--projn :: Int -> Q [Dec]-projn n = do- let p = mkName $ "proj" ++ show n- let gvars = map (\n -> mkName $ 'g' : show n) [1..n]- let avar = mkName "a"- let ivar = mkName "i"- let xvar = mkName "x"- let d = [funD p [clause [varP xvar] (normalB $ genDecl xvar gvars avar ivar) []]]- sequence $ (sigD p $ genSig gvars avar ivar) : d- where genSig gvars avar ivar = do- let fvar = mkName "f"- let cxt = map (\g -> classP ''(:<:) [varT g, varT fvar]) gvars- let tp = foldl1 (\a g -> conT ''(:+:) `appT` g `appT` a)- (map varT gvars)- let tp' = arrowT- `appT` (varT fvar `appT` varT avar `appT` varT ivar)- `appT` (conT ''Maybe `appT`- (tp `appT` varT avar `appT` varT ivar))- forallT (map PlainTV $ fvar : ivar : avar : gvars)- (sequence cxt) tp'- genDecl x [g] a i =- [| liftM inj (proj $(varE x)- :: Maybe ($(varT g `appT` varT a `appT` varT i))) |]- genDecl x (g:gs) a i =- [| case (proj $(varE x)- :: Maybe ($(varT g `appT` varT a `appT` varT i))) of- Just y -> Just $ inj y- _ -> $(genDecl x gs a i) |]- genDecl _ _ _ _ = error "genDecl called with empty list"--projectn :: Int -> Q [Dec]-projectn n = do- let p = mkName ("project" ++ show n)- let gvars = map (\n -> mkName $ 'g' : show n) [1..n]- let avar = mkName "a"- let ivar = mkName "i"- let xvar = mkName "x"- let d = [funD p [clause [varP xvar] (normalB $ genDecl xvar n) []]]- sequence $ (sigD p $ genSig gvars avar ivar) : d- where genSig gvars avar ivar = do- let fvar = mkName "f"- let hvar = mkName "h"- let cxt = map (\g -> classP ''(:<:) [varT g, varT fvar]) gvars- let tp = foldl1 (\a g -> conT ''(:+:) `appT` g `appT` a)- (map varT gvars)- let tp' = conT ''Cxt `appT` varT hvar `appT` varT fvar- `appT` varT avar- let tp'' = arrowT `appT` (tp' `appT` varT ivar)- `appT` (conT ''Maybe `appT`- (tp `appT` tp' `appT` varT ivar))- forallT (map PlainTV $ hvar : fvar : avar : ivar : gvars)- (sequence cxt) tp''- genDecl x n = [| case $(varE x) of- Hole _ -> Nothing- Term t -> $(varE $ mkName $ "proj" ++ show n) t |]--deepProjectn :: Int -> Q [Dec]-deepProjectn n = do- let p = mkName ("deepProject" ++ show n)- let gvars = map (\n -> mkName $ 'g' : show n) [1..n]- let d = [funD p [clause [] (normalB $ genDecl n) []]]- sequence $ (sigD p $ genSig gvars) : d- where genSig gvars = do- let fvar = mkName "f"- let cxt = map (\g -> classP ''(:<:) [varT g, varT fvar]) gvars- let tp = foldl1 (\a g -> conT ''(:+:) `appT` g `appT` a)- (map varT gvars)- let cxt' = classP ''HTraversable [tp]- let tp' = conT ''CxtFunM `appT` conT ''Maybe- `appT` varT fvar `appT` tp- forallT (map PlainTV $ fvar : gvars) (sequence $ cxt' : cxt) tp'- genDecl n = [| appSigFunM' $(varE $ mkName $ "proj" ++ show n) |]
src/Data/Comp/Multi/Derive/Show.hs view
@@ -1,4 +1,5 @@-{-# LANGUAGE TemplateHaskell, TypeOperators #-}+{-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE TypeOperators #-} -------------------------------------------------------------------------------- -- | -- Module : Data.Comp.Multi.Derive.Show@@ -20,8 +21,8 @@ ) where import Data.Comp.Derive.Utils-import Data.Comp.Multi.HFunctor import Data.Comp.Multi.Algebra+import Data.Comp.Multi.HFunctor import Language.Haskell.TH {-| Signature printing. An instance @ShowHF f@ gives rise to an instance@@ -43,26 +44,26 @@ kind taking at least two arguments. -} makeShowHF :: Name -> Q [Dec] makeShowHF fname = do- TyConI (DataD _cxt name args constrs _deriving) <- abstractNewtypeQ $ reify fname+ Just (DataInfo _cxt name args constrs _deriving) <- abstractNewtypeQ $ reify fname let args' = init args fArg = VarT . tyVarBndrName $ last args' argNames = map (VarT . tyVarBndrName) (init args') complType = foldl AppT (ConT name) argNames- preCond = map (ClassP ''Show . (: [])) argNames+ preCond = map (mkClassP ''Show . (: [])) argNames classType = AppT (ConT ''ShowHF) complType constrs' <- mapM normalConExp constrs showFDecl <- funD 'showHF (showFClauses fArg constrs')- return [InstanceD preCond classType [showFDecl]]+ return [mkInstanceD preCond classType [showFDecl]] where showFClauses fArg = map (genShowFClause fArg) filterFarg fArg ty x = (containsType ty fArg, varE x) mkShow (isFArg, var) | isFArg = [|unK $var|] | otherwise = [| show $var |]- genShowFClause fArg (constr, args) = do + genShowFClause fArg (constr, args, ty) = do let n = length args varNs <- newNames n "x"- let pat = ConP constr $ map VarP varNs- allVars = zipWith (filterFarg fArg) args varNs+ let pat = ConP constr [] $ map VarP varNs+ allVars = zipWith (filterFarg (getBinaryFArg fArg ty)) args varNs shows = listE $ map mkShow allVars conName = nameBase constr body <- [|K $ showConstr conName $shows|]
src/Data/Comp/Multi/Derive/SmartAConstructors.hs view
@@ -12,17 +12,17 @@ -- -------------------------------------------------------------------------------- -module Data.Comp.Multi.Derive.SmartAConstructors +module Data.Comp.Multi.Derive.SmartAConstructors ( smartAConstructors ) where -import Language.Haskell.TH hiding (Cxt)+import Control.Monad import Data.Comp.Derive.Utils+import Data.Comp.Multi.Annotation import Data.Comp.Multi.Sum import Data.Comp.Multi.Term-import Data.Comp.Multi.Annotation-import Control.Monad+import Language.Haskell.TH hiding (Cxt) {-| Derive smart constructors with products for a type constructor of any parametric kind taking at least two arguments. The smart constructors are@@ -30,13 +30,13 @@ inserted. -} smartAConstructors :: Name -> Q [Dec] smartAConstructors fname = do- TyConI (DataD _cxt tname targs constrs _deriving) <- abstractNewtypeQ $ reify fname+ Just (DataInfo _cxt _tname _targs constrs _deriving) <- abstractNewtypeQ $ reify fname let cons = map abstractConType constrs- liftM concat $ mapM (genSmartConstr (map tyVarBndrName targs) tname) cons- where genSmartConstr targs tname (name, args) = do+ liftM concat $ mapM genSmartConstr cons+ where genSmartConstr (name, args) = do let bname = nameBase name- genSmartConstr' targs tname (mkName $ "iA" ++ bname) name args- genSmartConstr' targs tname sname name args = do+ genSmartConstr' (mkName $ "iA" ++ bname) name args+ genSmartConstr' sname name args = do varNs <- newNames args "x" varPr <- newName "_p" let pats = map varP (varPr : varNs)
src/Data/Comp/Multi/Derive/SmartConstructors.hs view
@@ -12,30 +12,30 @@ -- -------------------------------------------------------------------------------- -module Data.Comp.Multi.Derive.SmartConstructors +module Data.Comp.Multi.Derive.SmartConstructors ( smartConstructors ) where -import Language.Haskell.TH hiding (Cxt)+import Control.Arrow ((&&&))+import Control.Monad import Data.Comp.Derive.Utils import Data.Comp.Multi.Sum import Data.Comp.Multi.Term-import Control.Arrow ((&&&))-import Control.Monad+import Language.Haskell.TH hiding (Cxt) {-| Derive smart constructors for a type constructor of any higher-order kind taking at least two arguments. The smart constructors are similar to the ordinary constructors, but an 'inject' is automatically inserted. -} smartConstructors :: Name -> Q [Dec] smartConstructors fname = do- TyConI (DataD _cxt tname targs constrs _deriving) <- abstractNewtypeQ $ reify fname+ Just (DataInfo _cxt tname targs constrs _deriving) <- abstractNewtypeQ $ reify fname let iVar = tyVarBndrName $ last targs let cons = map (abstractConType &&& iTp iVar) constrs liftM concat $ mapM (genSmartConstr (map tyVarBndrName targs) tname) cons where iTp iVar (ForallC _ cxt _) = -- Check if the GADT phantom type is constrained- case [y | EqualP x y <- cxt, x == VarT iVar] of+ case [y | Just (x, y) <- map isEqualP cxt, x == VarT iVar] of [] -> Nothing tp:_ -> Just tp iTp _ _ = Nothing@@ -62,8 +62,8 @@ a = varT avar i = varT ivar ftype = foldl appT (conT tname) (map varT targs')- constr = classP ''(:<:) [ftype, f]+ constr = (conT ''(:<:) `appT` ftype) `appT` f typ = foldl appT (conT ''Cxt) [h, f, a, maybe i return miTp]- typeSig = forallT (map PlainTV vars) (sequence [constr]) typ+ typeSig = forallT (map (\ v -> PlainTV v SpecifiedSpec) vars) (sequence [constr]) typ sigD sname typeSig genSig _ _ _ _ _ = []
src/Data/Comp/Multi/Desugar.hs view
@@ -1,5 +1,8 @@-{-# LANGUAGE TemplateHaskell, MultiParamTypeClasses, FlexibleInstances,- UndecidableInstances, TypeOperators, OverlappingInstances #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE TypeOperators #-}+{-# LANGUAGE UndecidableInstances #-} -------------------------------------------------------------------------------- -- | -- Module : Data.Comp.Multi.Desugar@@ -28,7 +31,7 @@ -- We make the lifting to sums explicit in order to make the Desugar -- class work with the default instance declaration further below.-instance (Desugar f h, Desugar g h) => Desugar (f :+: g) h where+instance {-# OVERLAPPABLE #-} (Desugar f h, Desugar g h) => Desugar (f :+: g) h where desugHom = caseH desugHom desugHom -- |Desugar a term.@@ -41,5 +44,5 @@ desugarA = appHom (propAnn desugHom) -- |Default desugaring instance.-instance (HFunctor f, HFunctor g, f :<: g) => Desugar f g where+instance {-# OVERLAPPABLE #-} (HFunctor f, HFunctor g, f :<: g) => Desugar f g where desugHom = simpCxt . inj
src/Data/Comp/Multi/Equality.hs view
@@ -1,4 +1,6 @@-{-# LANGUAGE TypeOperators, GADTs, FlexibleInstances #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE GADTs #-}+{-# LANGUAGE TypeOperators #-} -------------------------------------------------------------------------------- -- | -- Module : Data.Comp.Multi.Equality@@ -20,11 +22,10 @@ heqMod ) where -import Data.Comp.Multi.Term-import Data.Comp.Multi.Sum-import Data.Comp.Multi.Ops-import Data.Comp.Multi.HFunctor import Data.Comp.Multi.HFoldable+import Data.Comp.Multi.HFunctor+import Data.Comp.Multi.Ops+import Data.Comp.Multi.Term class KEq f where keq :: f i -> f j -> Bool
src/Data/Comp/Multi/Generic.hs view
@@ -1,4 +1,10 @@-{-# LANGUAGE GADTs, ExistentialQuantification, TypeOperators, ScopedTypeVariables, Rank2Types #-}+{-# LANGUAGE ConstraintKinds #-}+{-# LANGUAGE ExistentialQuantification #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE GADTs #-}+{-# LANGUAGE Rank2Types #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeOperators #-} -------------------------------------------------------------------------------- -- |@@ -17,13 +23,13 @@ module Data.Comp.Multi.Generic where -import Data.Comp.Multi.Term-import Data.Comp.Multi.Sum-import Data.Comp.Multi.HFunctor+import Control.Monad import Data.Comp.Multi.HFoldable+import Data.Comp.Multi.HFunctor import Data.Comp.Multi.HTraversable+import Data.Comp.Multi.Sum+import Data.Comp.Multi.Term import GHC.Exts-import Control.Monad import Prelude import Data.Maybe@@ -32,14 +38,14 @@ -- term. This function is similar to Uniplate's @universe@ function. subterms :: forall f . HFoldable f => Term f :=> [E (Term f)] subterms t = build (f t)- where f :: Term f :=> (E (Term f) -> b -> b) -> b -> b+ where f :: forall i b. Term f i -> (E (Term f) -> b -> b) -> b -> b f t cons nil = E t `cons` hfoldl (\u s -> f s cons u) nil (unTerm t) -- | This function returns a list of all subterms of the given term -- that are constructed from a particular functor. subterms' :: forall f g . (HFoldable f, g :<: f) => Term f :=> [E (g (Term f))] subterms' (Term t) = build (f t)- where f :: f (Term f) :=> (E (g (Term f)) -> b -> b) -> b -> b+ where f :: forall i b. f (Term f) i -> (E (g (Term f)) -> b -> b) -> b -> b f t cons nil = let rest = hfoldl (\u (Term s) -> f s cons u) nil t in case proj t of Just t' -> E t' `cons` rest@@ -57,12 +63,12 @@ -- | Monadic version of 'transform'. transformM :: forall f m . (HTraversable f, Monad m) => NatM m (Term f) (Term f) -> NatM m (Term f) (Term f)-transformM f = run +transformM f = run where run :: NatM m (Term f) (Term f) run t = f =<< liftM Term (hmapM run $ unTerm t) query :: HFoldable f => (Term f :=> r) -> (r -> r -> r) -> Term f :=> r--- query q c = run +-- query q c = run -- where run i@(Term t) = foldl (\s x -> s `c` run x) (q i) t query q c i@(Term t) = hfoldl (\s x -> s `c` query q c x) (q i) t
src/Data/Comp/Multi/HFoldable.hs view
@@ -1,4 +1,10 @@-{-# LANGUAGE RankNTypes, TypeOperators, FlexibleInstances, ScopedTypeVariables, GADTs, MultiParamTypeClasses, UndecidableInstances, IncoherentInstances #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE GADTs #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeOperators #-}+{-# LANGUAGE UndecidableInstances #-} -------------------------------------------------------------------------------- -- |@@ -21,9 +27,9 @@ htoList ) where -import Data.Monoid-import Data.Maybe import Data.Comp.Multi.HFunctor+import Data.Maybe+import Data.Monoid -- | Higher-order functors that can be folded. --@@ -35,7 +41,7 @@ hfoldMap :: Monoid m => (a :=> m) -> h a :=> m hfoldMap f = hfoldr (mappend . f) mempty - hfoldr :: (a :=> b -> b) -> b -> h a :=> b+ hfoldr :: (a :=> (b->b) ) -> b -> h a :=> b hfoldr f z t = appEndo (hfoldMap (Endo . f) t) z hfoldl :: (b -> a :=> b) -> b -> h a :=> b@@ -45,7 +51,7 @@ hfoldr1 :: forall a. (a -> a -> a) -> h (K a) :=> a hfoldr1 f xs = fromMaybe (error "hfoldr1: empty structure") (hfoldr mf Nothing xs)- where mf :: K a :=> Maybe a -> Maybe a+ where mf :: K a :=> (Maybe a -> Maybe a) mf (K x) Nothing = Just x mf (K x) (Just y) = Just (f x y) @@ -58,7 +64,7 @@ htoList :: (HFoldable f) => f a :=> [E a] htoList = hfoldr (\ n l -> E n : l) []- + kfoldr :: (HFoldable f) => (a -> b -> b) -> b -> f (K a) :=> b kfoldr f = hfoldr (\ (K x) y -> f x y)
src/Data/Comp/Multi/HFunctor.hs view
@@ -1,4 +1,15 @@-{-# LANGUAGE Rank2Types, TypeOperators, FlexibleInstances, ScopedTypeVariables, GADTs, MultiParamTypeClasses, UndecidableInstances, IncoherentInstances #-}+{-# LANGUAGE KindSignatures #-}+{-# LANGUAGE DeriveTraversable #-}+{-# LANGUAGE DeriveFoldable #-}+{-# LANGUAGE DeriveFunctor #-}+{-# LANGUAGE ExistentialQuantification #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE Rank2Types #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeOperators #-}+{-# LANGUAGE UndecidableInstances #-}+{-# LANGUAGE IncoherentInstances #-} -------------------------------------------------------------------------------- -- |@@ -28,14 +39,15 @@ (:.:)(..) ) where +import Data.Functor.Compose+import Data.Kind+ -- | The identity Functor.-newtype I a = I {unI :: a}+newtype I a = I {unI :: a} deriving (Functor, Foldable, Traversable) --- | The parametrised constant functor.-newtype K a i = K {unK :: a} -instance Functor (K a) where- fmap _ (K x) = K x+-- | The parametrised constant functor.+newtype K a i = K {unK :: a} deriving (Functor, Foldable, Traversable) data E f = forall i. E {unE :: f i} @@ -78,7 +90,7 @@ -- functor @f g@. -- -- @ffmap :: (Functor g) => (a -> b) -> f g a -> f g b@- -- + -- -- We omit this, as it does not work for GADTs (see Johand and -- Ghani 2008). @@ -86,7 +98,9 @@ -- @g :-> h@ to a natural transformation @f g :-> f h@ hfmap :: (f :-> g) -> h f :-> h g +instance (Functor f) => HFunctor (Compose f) where hfmap f (Compose xs) = Compose (fmap f xs)+ infixl 5 :.: -- | This data type denotes the composition of two functor families.-data (f :.: g) e t = Comp f (g e) t+data (:.:) f (g :: (Type -> Type) -> (Type -> Type)) (e :: Type -> Type) t = Comp (f (g e) t)
src/Data/Comp/Multi/HTraversable.hs view
@@ -1,4 +1,10 @@-{-# LANGUAGE Rank2Types, TypeOperators, FlexibleInstances, ScopedTypeVariables, GADTs, MultiParamTypeClasses, UndecidableInstances, IncoherentInstances #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE GADTs #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE Rank2Types #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeOperators #-}+{-# LANGUAGE UndecidableInstances #-} -------------------------------------------------------------------------------- -- |@@ -18,9 +24,9 @@ HTraversable (..) ) where -import Data.Comp.Multi.HFunctor+ import Data.Comp.Multi.HFoldable-import Control.Applicative+import Data.Comp.Multi.HFunctor class HFoldable t => HTraversable t where @@ -30,7 +36,10 @@ -- Alternative type in terms of natural transformations using -- functor composition @:.:@: --- -- @hmapM :: Monad m => (a :-> m :.: b) -> t a :-> m :.: (t b)@+ -- @+ -- hmapM :: Monad m => (a :-> m :.: b) -> t a :-> m :.: (t b)+ -- @+ -- hmapM :: (Monad m) => NatM m a b -> NatM m (t a) (t b) htraverse :: (Applicative f) => NatM f a b -> NatM f (t a) (t b)
+ src/Data/Comp/Multi/Mapping.hs view
@@ -0,0 +1,95 @@+{-# LANGUAGE KindSignatures #-}+{-# LANGUAGE FunctionalDependencies #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE TupleSections #-}+{-# LANGUAGE TypeOperators #-}+{-# LANGUAGE GeneralizedNewtypeDeriving #-}+{-# LANGUAGE FlexibleContexts #-}+--------------------------------------------------------------------------------+-- |+-- Module : Data.Comp.Multi.Mapping+-- Copyright : (c) 2014 Patrick Bahr+-- License : BSD3+-- Maintainer : Patrick Bahr <paba@diku.dk>+-- Stability : experimental+-- Portability : non-portable (GHC Extensions)+--+-- This module provides functionality to construct mappings from+-- positions in a functorial value.+--+--------------------------------------------------------------------------------++module Data.Comp.Multi.Mapping+ ( Numbered (..)+ , unNumbered+ , number+ , HTraversable ()+ , Mapping (..)+ , lookupNumMap) where++import Data.Comp.Multi.HFunctor+import Data.Comp.Multi.HTraversable++import Data.Kind++import Control.Monad.State++import Data.IntMap (IntMap)+import qualified Data.IntMap as IntMap+++-- | This type is used for numbering components of a functorial value.+data Numbered a i = Numbered Int (a i)++unNumbered :: Numbered a :-> a+unNumbered (Numbered _ x) = x+++-- | This function numbers the components of the given functorial+-- value with consecutive integers starting at 0.+number :: HTraversable f => f a :-> f (Numbered a)+number x = evalState (hmapM run x) 0 where+ run b = do n <- get+ put (n+1)+ return $ Numbered n b++++infix 1 |->+infixr 0 &+++class Mapping m (k :: Type -> Type) | m -> k where+ -- | left-biased union of two mappings.+ (&) :: m v -> m v -> m v++ -- | This operator constructs a singleton mapping.+ (|->) :: k i -> v -> m v++ -- | This is the empty mapping.+ empty :: m v++ -- | This function constructs the pointwise product of two maps each+ -- with a default value.+ prodMap :: v1 -> v2 -> m v1 -> m v2 -> m (v1, v2)++ -- | Returns the value at the given key or returns the given+ -- default when the key is not an element of the map.+ findWithDefault :: a -> k i -> m a -> a+++newtype NumMap (k :: Type -> Type) v = NumMap (IntMap v) deriving Functor++lookupNumMap :: a -> Int -> NumMap t a -> a+lookupNumMap d k (NumMap m) = IntMap.findWithDefault d k m++instance Mapping (NumMap k) (Numbered k) where+ NumMap m1 & NumMap m2 = NumMap (IntMap.union m1 m2)+ Numbered k _ |-> v = NumMap $ IntMap.singleton k v+ empty = NumMap IntMap.empty++ findWithDefault d (Numbered i _) m = lookupNumMap d i m++ prodMap p q (NumMap mp) (NumMap mq) = NumMap $ IntMap.mergeWithKey merge + (IntMap.map (,q)) (IntMap.map (p,)) mp mq+ where merge _ p q = Just (p,q)
− src/Data/Comp/Multi/Number.hs
@@ -1,50 +0,0 @@-{-# LANGUAGE TypeOperators #-}------------------------------------------------------------------------------------- |--- Module : Data.Comp.Multi.Number--- Copyright : (c) 2012 Patrick Bahr--- License : BSD3--- Maintainer : Patrick Bahr <paba@diku.dk>--- Stability : experimental--- Portability : non-portable (GHC Extensions)--- --- This module provides functionality to number the components of a--- functorial value with consecutive integers.--------------------------------------------------------------------------------------module Data.Comp.Multi.Number - ( Numbered (..)- , unNumbered- , number- , HTraversable ()) where--import Data.Comp.Multi.HTraversable-import Data.Comp.Multi.HFunctor-import Data.Comp.Multi.Ordering-import Data.Comp.Multi.Equality---import Control.Monad.State----- | This type is used for numbering components of a functorial value.-newtype Numbered a i = Numbered (Int, a i)--unNumbered :: Numbered a :-> a-unNumbered (Numbered (_, x)) = x--instance KEq (Numbered a) where- keq (Numbered (i,_)) (Numbered (j,_)) = i == j--instance KOrd (Numbered a) where- kcompare (Numbered (i,_)) (Numbered (j,_)) = i `compare` j---- | This function numbers the components of the given functorial--- value with consecutive integers starting at 0.-number :: HTraversable f => f a :-> f (Numbered a)-number x = fst $ runState (hmapM run x) 0 where- run b = do n <- get- put (n+1)- return $ Numbered (n,b)
src/Data/Comp/Multi/Ops.hs view
@@ -1,8 +1,18 @@-{-# LANGUAGE TypeOperators, MultiParamTypeClasses, IncoherentInstances,- FlexibleInstances, FlexibleContexts, GADTs, TypeSynonymInstances,- ScopedTypeVariables, FunctionalDependencies, UndecidableInstances, KindSignatures, RankNTypes{-|- --} #-}+{-# LANGUAGE ConstraintKinds #-}+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE FunctionalDependencies #-}+{-# LANGUAGE GADTs #-}+{-# LANGUAGE KindSignatures #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE PolyKinds #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE TypeOperators #-}+{-# LANGUAGE TypeSynonymInstances #-}+{-# LANGUAGE UndecidableInstances #-} -------------------------------------------------------------------------------- -- |@@ -18,22 +28,30 @@ -- -------------------------------------------------------------------------------- -module Data.Comp.Multi.Ops where+module Data.Comp.Multi.Ops + ( module Data.Comp.Multi.Ops+ , (O.:*:)(..)+ , O.ffst+ , O.fsnd+ ) where -import Data.Comp.Multi.HFunctor++import Control.Monad+import Data.Kind+ import Data.Comp.Multi.HFoldable+import Data.Comp.Multi.HFunctor import Data.Comp.Multi.HTraversable import qualified Data.Comp.Ops as O-import Control.Monad-import Control.Applicative +import Data.Comp.SubsumeCommon -infixr 5 :+:+infixr 6 :+: -- |Data type defining coproducts.-data (f :+: g) (h :: * -> *) e = Inl (f h e)- | Inr (g h e)+data (f :+: g) (h :: Type -> Type) e = Inl (f h e)+ | Inr (g h e) {-| Utility function to case on a higher-order functor sum, without exposing the internal representation of sums. -}@@ -67,50 +85,87 @@ hmapM f (Inl e) = Inl `liftM` hmapM f e hmapM f (Inr e) = Inr `liftM` hmapM f e --- |The subsumption relation.-class (sub :: (* -> *) -> * -> *) :<: sup where- inj :: sub a :-> sup a- proj :: NatM Maybe (sup a) (sub a)+-- The subsumption relation. -instance (:<:) f f where- inj = id- proj = Just+infixl 5 :<:+infixl 5 :=: -instance (:<:) f (f :+: g) where- inj = Inl- proj (Inl x) = Just x- proj (Inr _) = Nothing+type family Elem (f :: (Type -> Type) -> Type -> Type)+ (g :: (Type -> Type) -> Type -> Type) :: Emb where+ Elem f f = Found Here+ Elem (f1 :+: f2) g = Sum' (Elem f1 g) (Elem f2 g)+ Elem f (g1 :+: g2) = Choose (Elem f g1) (Elem f g2)+ Elem f g = NotFound -instance (f :<: g) => (:<:) f (h :+: g) where- inj = Inr . inj- proj (Inr x) = proj x- proj (Inl _) = Nothing+class Subsume (e :: Emb) (f :: (Type -> Type) -> Type -> Type)+ (g :: (Type -> Type) -> Type -> Type) where+ inj' :: Proxy e -> f a :-> g a+ prj' :: Proxy e -> NatM Maybe (g a) (f a) --- Products+instance Subsume (Found Here) f f where+ inj' _ = id -infixr 8 :*:+ prj' _ = Just -data (f :*: g) a = f a :*: g a+instance Subsume (Found p) f g => Subsume (Found (Le p)) f (g :+: g') where+ inj' _ = Inl . inj' (P :: Proxy (Found p)) + prj' _ (Inl x) = prj' (P :: Proxy (Found p)) x+ prj' _ _ = Nothing -fst :: (f :*: g) a -> f a-fst (x :*: _) = x+instance Subsume (Found p) f g => Subsume (Found (Ri p)) f (g' :+: g) where+ inj' _ = Inr . inj' (P :: Proxy (Found p)) -snd :: (f :*: g) a -> g a-snd (_ :*: x) = x+ prj' _ (Inr x) = prj' (P :: Proxy (Found p)) x+ prj' _ _ = Nothing +instance (Subsume (Found p1) f1 g, Subsume (Found p2) f2 g)+ => Subsume (Found (Sum p1 p2)) (f1 :+: f2) g where+ inj' _ (Inl x) = inj' (P :: Proxy (Found p1)) x+ inj' _ (Inr x) = inj' (P :: Proxy (Found p2)) x++ prj' _ x = case prj' (P :: Proxy (Found p1)) x of+ Just y -> Just (Inl y)+ _ -> case prj' (P :: Proxy (Found p2)) x of+ Just y -> Just (Inr y)+ _ -> Nothing++++-- | A constraint @f :<: g@ expresses that the signature @f@ is+-- subsumed by @g@, i.e. @f@ can be used to construct elements in @g@.+type f :<: g = (Subsume (ComprEmb (Elem f g)) f g)+++inj :: forall f g a . (f :<: g) => f a :-> g a+inj = inj' (P :: Proxy (ComprEmb (Elem f g)))++proj :: forall f g a . (f :<: g) => NatM Maybe (g a) (f a)+proj = prj' (P :: Proxy (ComprEmb (Elem f g)))++type f :=: g = (f :<: g, g :<: f)++++spl :: (f :=: f1 :+: f2) => (f1 a :-> b) -> (f2 a :-> b) -> f a :-> b+spl f1 f2 x = case inj x of+ Inl y -> f1 y+ Inr y -> f2 y+ -- Constant Products infixr 7 :&: -- | This data type adds a constant product to a -- signature. Alternatively, this could have also been defined as--- --- @data (f :&: a) (g :: * -> *) e = f g e :&: a e@--- +--+-- @+-- data (f :&: a) (g :: Type -> Type) e = f g e :&: a e+-- @+-- -- This is too general, however, for example for 'productHHom'. -data (f :&: a) (g :: * -> *) e = f g e :&: a+data (f :&: a) (g :: Type -> Type) e = f g e :&: a instance (HFunctor f) => HFunctor (f :&: a) where@@ -131,13 +186,13 @@ -- | This class defines how to distribute an annotation over a sum of -- signatures.-class DistAnn (s :: (* -> *) -> * -> *) p s' | s' -> s, s' -> p where+class DistAnn (s :: (Type -> Type) -> Type -> Type) p s' | s' -> s, s' -> p where -- | This function injects an annotation over a signature. injectA :: p -> s a :-> s' a projectA :: s' a :-> (s a O.:&: p) -class RemA (s :: (* -> *) -> * -> *) s' | s -> s' where+class RemA (s :: (Type -> Type) -> Type -> Type) s' | s -> s' where remA :: s a :-> s' a
src/Data/Comp/Multi/Ordering.hs view
@@ -1,5 +1,8 @@-{-# LANGUAGE TypeOperators, TypeSynonymInstances, FlexibleInstances,- UndecidableInstances, IncoherentInstances, GADTs #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE GADTs #-}+{-# LANGUAGE TypeOperators #-}+{-# LANGUAGE TypeSynonymInstances #-}+{-# LANGUAGE UndecidableInstances #-} -------------------------------------------------------------------------------- -- | -- Module : Data.Comp.Multi.Ordering@@ -19,11 +22,10 @@ OrdHF(..) ) where -import Data.Comp.Multi.Term-import Data.Comp.Multi.Sum-import Data.Comp.Multi.Ops-import Data.Comp.Multi.HFunctor import Data.Comp.Multi.Equality+import Data.Comp.Multi.HFunctor+import Data.Comp.Multi.Ops+import Data.Comp.Multi.Term class KEq f => KOrd f where kcompare :: f i -> f j -> Ordering
+ src/Data/Comp/Multi/Projection.hs view
@@ -0,0 +1,77 @@+{-# LANGUAGE ConstraintKinds #-}+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE KindSignatures #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE TypeOperators #-}+{-# LANGUAGE UndecidableInstances #-}++++--------------------------------------------------------------------------------+-- |+-- Module : Data.Comp.Multi.Projection+-- Copyright : (c) 2014 Patrick Bahr+-- License : BSD3+-- Maintainer : Patrick Bahr <paba@di.ku.dk>+-- Stability : experimental+-- Portability : non-portable (GHC Extensions)+--+-- This module provides a generic projection function 'pr' for+-- arbitrary nested binary products.+--+--------------------------------------------------------------------------------+++module Data.Comp.Multi.Projection (pr, (:<), (:*:)(..), ffst, fsnd) where++import Data.Comp.SubsumeCommon+import Data.Comp.Multi.Ops hiding (Elem)++import Data.Kind++type family Elem (f :: Type -> Type)+ (g :: Type -> Type) :: Emb where+ Elem f f = Found Here+ Elem (f1 :*: f2) g = Sum' (Elem f1 g) (Elem f2 g)+ Elem f (g1 :*: g2) = Choose (Elem f g1) (Elem f g2)+ Elem f g = NotFound++class Proj (e :: Emb) (p :: Type -> Type)+ (q :: Type -> Type) where+ pr' :: Proxy e -> q a -> p a++instance Proj (Found Here) f f where+ pr' _ = id++instance Proj (Found p) f g => Proj (Found (Le p)) f (g :*: g') where+ pr' _ = pr' (P :: Proxy (Found p)) . ffst+++instance Proj (Found p) f g => Proj (Found (Ri p)) f (g' :*: g) where+ pr' _ = pr' (P :: Proxy (Found p)) . fsnd+++instance (Proj (Found p1) f1 g, Proj (Found p2) f2 g)+ => Proj (Found (Sum p1 p2)) (f1 :*: f2) g where+ pr' _ x = (pr' (P :: Proxy (Found p1)) x :*: pr' (P :: Proxy (Found p2)) x)+++infixl 5 :<++-- | The constraint @e :< p@ expresses that @e@ is a component of the+-- type @p@. That is, @p@ is formed by binary products using the type+-- @e@. The occurrence of @e@ must be unique. For example we have @Int+-- :< (Bool,(Int,Bool))@ but not @Bool :< (Bool,(Int,Bool))@.++type f :< g = (Proj (ComprEmb (Elem f g)) f g)+++-- | This function projects the component of type @e@ out or the+-- compound value of type @p@.++pr :: forall p q a . (p :< q) => q a -> p a+pr = pr' (P :: Proxy (ComprEmb (Elem p q)))
src/Data/Comp/Multi/Show.hs view
@@ -1,6 +1,9 @@-{-# LANGUAGE TypeOperators, GADTs, FlexibleContexts,- ScopedTypeVariables, UndecidableInstances, FlexibleInstances,- TemplateHaskell #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE GADTs #-}+{-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE TypeOperators #-}+{-# LANGUAGE UndecidableInstances #-} -------------------------------------------------------------------------------- -- | -- Module : Data.Comp.Multi.Show@@ -20,11 +23,11 @@ ( ShowHF(..) ) where -import Data.Comp.Multi.Term-import Data.Comp.Multi.Annotation import Data.Comp.Multi.Algebra-import Data.Comp.Multi.HFunctor+import Data.Comp.Multi.Annotation import Data.Comp.Multi.Derive+import Data.Comp.Multi.HFunctor+import Data.Comp.Multi.Term instance KShow (K String) where kshow = id
src/Data/Comp/Multi/Sum.hs view
@@ -1,5 +1,9 @@-{-# LANGUAGE TypeOperators, GADTs, ScopedTypeVariables, IncoherentInstances,- Rank2Types, FlexibleContexts, TemplateHaskell #-}+{-# LANGUAGE ConstraintKinds #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE GADTs #-}+{-# LANGUAGE Rank2Types #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeOperators #-} -------------------------------------------------------------------------------- -- | -- Module : Data.Comp.Multi.Sum@@ -22,72 +26,18 @@ -- * Projections for Signatures and Terms proj,- proj2,- proj3,- proj4,- proj5,- proj6,- proj7,- proj8,- proj9,- proj10, project,- project2,- project3,- project4,- project5,- project6,- project7,- project8,- project9,- project10, deepProject,- deepProject2,- deepProject3,- deepProject4,- deepProject5,- deepProject6,- deepProject7,- deepProject8,- deepProject9,- deepProject10, -- * Injections for Signatures and Terms inj,- inj2,- inj3,- inj4,- inj5,- inj6,- inj7,- inj8,- inj9,- inj10, inject,- inject2,- inject3,- inject4,- inject5,- inject6,- inject7,- inject8,- inject9,- inject10, deepInject,- deepInject2,- deepInject3,- deepInject4,- deepInject5,- deepInject6,- deepInject7,- deepInject8,- deepInject9,- deepInject10, + split,+ -- * Injections and Projections for Constants injectConst,- injectConst2,- injectConst3, projectConst, injectCxt, liftCxt,@@ -95,16 +45,12 @@ -- substHoles' ) where +import Data.Comp.Multi.Algebra import Data.Comp.Multi.HFunctor import Data.Comp.Multi.HTraversable import Data.Comp.Multi.Ops import Data.Comp.Multi.Term-import Data.Comp.Multi.Algebra-import Data.Comp.Multi.Derive.Projections-import Data.Comp.Multi.Derive.Injections-import Control.Monad (liftM) -$(liftM concat $ mapM projn [2..10]) -- |Project the outermost layer of a term to a sub signature. If the signature -- @g@ is compound of /n/ atomic signatures, use @project@/n/ instead.@@ -112,7 +58,6 @@ project (Hole _) = Nothing project (Term t) = proj t -$(liftM concat $ mapM projectn [2..10]) -- | Tries to coerce a term/context to a term/context over a sub-signature. If -- the signature @g@ is compound of /n/ atomic signatures, use@@ -121,25 +66,12 @@ {-# INLINE deepProject #-} deepProject = appSigFunM' proj -$(liftM concat $ mapM deepProjectn [2..10])-{-# INLINE deepProject2 #-}-{-# INLINE deepProject3 #-}-{-# INLINE deepProject4 #-}-{-# INLINE deepProject5 #-}-{-# INLINE deepProject6 #-}-{-# INLINE deepProject7 #-}-{-# INLINE deepProject8 #-}-{-# INLINE deepProject9 #-}-{-# INLINE deepProject10 #-} -$(liftM concat $ mapM injn [2..10])- -- |Inject a term where the outermost layer is a sub signature. If the signature -- @g@ is compound of /n/ atomic signatures, use @inject@/n/ instead. inject :: (g :<: f) => g (Cxt h f a) :-> Cxt h f a inject = Term . inj -$(liftM concat $ mapM injectn [2..10]) -- |Inject a term over a sub signature to a term over larger signature. If the -- signature @g@ is compound of /n/ atomic signatures, use @deepInject@/n/@@ -148,17 +80,11 @@ {-# INLINE deepInject #-} deepInject = appSigFun inj -$(liftM concat $ mapM deepInjectn [2..10])-{-# INLINE deepInject2 #-}-{-# INLINE deepInject3 #-}-{-# INLINE deepInject4 #-}-{-# INLINE deepInject5 #-}-{-# INLINE deepInject6 #-}-{-# INLINE deepInject7 #-}-{-# INLINE deepInject8 #-}-{-# INLINE deepInject9 #-}-{-# INLINE deepInject10 #-} +split :: (f :=: f1 :+: f2) => (f1 (Term f) :-> a) -> (f2 (Term f) :-> a) -> Term f :-> a+split f1 f2 (Term t) = spl f1 f2 t++ -- | This function injects a whole context into another context. injectCxt :: (HFunctor g, g :<: f) => Cxt h' g (Cxt h f a) :-> Cxt h f a injectCxt = cata' inject@@ -177,15 +103,6 @@ injectConst :: (HFunctor g, g :<: f) => Const g :-> Cxt h f a injectConst = inject . hfmap (const undefined)--injectConst2 :: (HFunctor f1, HFunctor f2, HFunctor g, f1 :<: g, f2 :<: g)- => Const (f1 :+: f2) :-> Cxt h g a-injectConst2 = inject2 . hfmap (const undefined)--injectConst3 :: (HFunctor f1, HFunctor f2, HFunctor f3, HFunctor g,- f1 :<: g, f2 :<: g, f3 :<: g)- => Const (f1 :+: f2 :+: f3) :-> Cxt h g a-injectConst3 = inject3 . hfmap (const undefined) projectConst :: (HFunctor g, g :<: f) => NatM Maybe (Cxt h f a) (Const g) projectConst = fmap (hfmap (const (K ()))) . project
src/Data/Comp/Multi/Term.hs view
@@ -1,5 +1,9 @@-{-# LANGUAGE EmptyDataDecls, GADTs, KindSignatures, RankNTypes,- TypeOperators, ScopedTypeVariables, IncoherentInstances #-}+{-# LANGUAGE EmptyDataDecls #-}+{-# LANGUAGE GADTs #-}+{-# LANGUAGE KindSignatures #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeOperators #-} -------------------------------------------------------------------------------- -- | -- Module : Data.Comp.Multi.Term@@ -15,7 +19,7 @@ -- -------------------------------------------------------------------------------- -module Data.Comp.Multi.Term +module Data.Comp.Multi.Term (Cxt (..), Hole, NoHole,@@ -28,17 +32,17 @@ simpCxt ) where -import Data.Comp.Multi.HFunctor import Data.Comp.Multi.HFoldable+import Data.Comp.Multi.HFunctor import Data.Comp.Multi.HTraversable-import Data.Monoid +import Data.Kind+ import Control.Monad-import Control.Applicative hiding (Const) import Unsafe.Coerce -type Const (f :: (* -> *) -> * -> *) = f (K ())+type Const (f :: (Type -> Type) -> Type -> Type) = f (K ()) -- | This function converts a constant to a term. This assumes that -- the argument is indeed a constant, i.e. does not have a value for@@ -79,9 +83,9 @@ instance (HFoldable f) => HFoldable (Cxt h f) where hfoldr = hfoldr' where- hfoldr' :: forall a b. (a :=> b -> b) -> b -> Cxt h f a :=> b+ hfoldr' :: forall a b. (a :=> (b -> b)) -> b -> Cxt h f a :=> b hfoldr' op c a = run a c where- run :: (Cxt h f) a :=> b -> b+ run :: (Cxt h f) a :=> (b -> b) run (Hole a) e = a `op` e run (Term t) e = hfoldr run e t
src/Data/Comp/Multi/Variables.hs view
@@ -1,5 +1,12 @@-{-# LANGUAGE MultiParamTypeClasses, GADTs, FlexibleInstances,- OverlappingInstances, TypeOperators, KindSignatures, FlexibleContexts, ScopedTypeVariables, RankNTypes, TemplateHaskell #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE GADTs #-}+{-# LANGUAGE KindSignatures #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE TypeOperators #-} -------------------------------------------------------------------------------- -- | -- Module : Data.Comp.Multi.Variables@@ -28,17 +35,21 @@ variables', appSubst, compSubst,- getBoundVars+ getBoundVars,+ (&),+ (|->),+ empty ) where -import Data.Comp.Multi.Term-import Data.Comp.Multi.Ordering-import Data.Comp.Multi.Number-import Data.Comp.Multi.Ops import Data.Comp.Multi.Algebra import Data.Comp.Multi.Derive-import Data.Comp.Multi.HFunctor import Data.Comp.Multi.HFoldable+import Data.Comp.Multi.HFunctor+import Data.Comp.Multi.Mapping+import Data.Comp.Multi.Ops+import Data.Comp.Multi.Term++import Data.Kind import Data.Map (Map) import qualified Data.Map as Map import Data.Set (Set)@@ -61,38 +72,42 @@ {-| This multiparameter class defines functors with variables. An instance @HasVar f v@ denotes that values over @f@ might contain and bind variables of type @v@. -}-class HasVars (f :: (* -> *) -> * -> *) v where+class HasVars (f :: (Type -> Type) -> Type -> Type) v where -- | Indicates whether the @f@ constructor is a variable. The -- default implementation returns @Nothing@. isVar :: f a :=> Maybe v isVar _ = Nothing- + -- | Indicates the set of variables bound by the @f@ constructor -- for each argument of the constructor. For example for a -- non-recursive let binding:+ -- -- @ -- data Let i e = Let Var (e i) (e i) -- instance HasVars Let Var where- -- bindsVars (Let v x y) = Map.fromList [(y, (Set.singleton v))]+ -- bindsVars (Let v x y) = y |-> Set.singleton v -- @+ -- -- If, instead, the let binding is recursive, the methods has to -- be implemented like this:+ -- -- @- -- bindsVars (Let v x y) = Map.fromList [(x, (Set.singleton v)),- -- (y, (Set.singleton v))]+ -- bindsVars (Let v x y) = x |-> Set.singleton v &+ -- y |-> Set.singleton v -- @+ -- -- This indicates that the scope of the bound variable also -- extends to the right-hand side of the variable binding. -- -- The default implementation returns the empty map.- bindsVars :: KOrd a => f a :=> Map (E a) (Set v)- bindsVars _ = Map.empty+ bindsVars :: Mapping m a => f a :=> m (Set v)+ bindsVars _ = empty $(derive [liftSum] [''HasVars])- + -- | Same as 'isVar' but it returns Nothing@ instead of @Just v@ if -- @v@ is contained in the given set of variables.- + isVar' :: (HasVars f v, Ord v) => Set v -> f a :=> Maybe v isVar' b t = do v <- isVar t if v `Set.member` b@@ -105,32 +120,29 @@ getBoundVars :: forall f a v i . (HasVars f v, HTraversable f) => f a i -> f (a :*: K (Set v)) i getBoundVars t = let n :: f (Numbered a) i n = number t- m :: Map (E (Numbered a)) (Set v) m = bindsVars n trans :: Numbered a :-> (a :*: K (Set v))- trans x = unNumbered x :*: (K (Map.findWithDefault Set.empty (E x) m))+ trans (Numbered i x) = x :*: K (lookupNumMap Set.empty i m) in hfmap trans n- + -- | This combinator combines 'getBoundVars' with the 'mfmap' function.-hfmapBoundVars :: forall f a b v i . (HasVars f v, HTraversable f) +hfmapBoundVars :: forall f a b v i . (HasVars f v, HTraversable f) => (Set v -> a :-> b) -> f a i -> f b i hfmapBoundVars f t = let n :: f (Numbered a) i n = number t- m :: Map (E (Numbered a)) (Set v) m = bindsVars n trans :: Numbered a :-> b- trans x = f (Map.findWithDefault Set.empty (E x) m) (unNumbered x)+ trans (Numbered i x) = f (lookupNumMap Set.empty i m) x in hfmap trans n- --- | This combinator combines 'getBoundVars' with the generic 'hfoldl' function. -hfoldlBoundVars :: forall f a b v i . (HasVars f v, HTraversable f) ++-- | This combinator combines 'getBoundVars' with the generic 'hfoldl' function.+hfoldlBoundVars :: forall f a b v i . (HasVars f v, HTraversable f) => (b -> Set v -> a :=> b) -> b -> f a i -> b hfoldlBoundVars f e t = let n :: f (Numbered a) i n = number t- m :: Map (E (Numbered a)) (Set v) m = bindsVars n trans :: b -> Numbered a :=> b- trans x y = f x (Map.findWithDefault Set.empty (E y) m) (unNumbered y)+ trans x (Numbered i y) = f x (lookupNumMap Set.empty i m) y in hfoldl trans e n @@ -145,17 +157,17 @@ alg t = C $ \vars -> case isVar t of Just v | not (v `Set.member` vars) -> Hole $ K v _ -> Term $ hfmapBoundVars run t- where + where run :: Set v -> C (Set v) (Context f (K v)) :-> Context f (K v) run newVars f = f `unC` (newVars `Set.union` vars)- + -- | Convert variables to holes, except those that are bound. containsVarAlg :: forall v f . (Ord v, HasVars f v, HTraversable f) => v -> Alg f (K Bool) containsVarAlg v t = K $ hfoldlBoundVars run local t where local = case isVar t of Just v' -> v == v' Nothing -> False- run :: Bool -> Set v -> (K Bool i) -> Bool+ run :: Bool -> Set v -> K Bool i -> Bool run acc vars (K b) = acc || (not (v `Set.member` vars) && b) {-| This function checks whether a variable is contained in a context. -}@@ -198,19 +210,20 @@ appSubst :: (Ord v, SubstVars v t a) => GSubst v t -> a :-> a appSubst subst = substVars (substFun subst) -instance (Ord v, HasVars f v, HTraversable f) => SubstVars v (Cxt h f a) (Cxt h f a) where+instance {-# OVERLAPPABLE #-} (Ord v, HasVars f v, HTraversable f)+ => SubstVars v (Cxt h f a) (Cxt h f a) where -- have to use explicit GADT pattern matching!! substVars subst = doSubst Set.empty where doSubst :: Set v -> Cxt h f a :-> Cxt h f a doSubst _ (Hole a) = Hole a- doSubst b (Term t) = case isVar' b t >>= subst . K of + doSubst b (Term t) = case isVar' b t >>= subst . K of Just new -> new Nothing -> Term $ hfmapBoundVars run t where run :: Set v -> Cxt h f a :-> Cxt h f a- run vars s = doSubst (b `Set.union` vars) s+ run vars = doSubst (b `Set.union` vars) -instance (SubstVars v t a, HFunctor f) => SubstVars v t (f a) where- substVars subst = hfmap (substVars subst) +instance {-# OVERLAPPABLE #-} (SubstVars v t a, HFunctor f) => SubstVars v t (f a) where+ substVars subst = hfmap (substVars subst) {-| This function composes two substitutions @s1@ and @s2@. That is, applying the resulting substitution is equivalent to first applying@@ -218,5 +231,4 @@ compSubst :: (Ord v, HasVars f v, HTraversable f) => CxtSubst h a f v -> CxtSubst h a f v -> CxtSubst h a f v-compSubst s1 s2 = Map.map f s2- where f (A t) = A (appSubst s1 t)+compSubst s1 = Map.map (\ (A t) -> A (appSubst s1 t))
− src/Data/Comp/MultiParam.hs
@@ -1,34 +0,0 @@------------------------------------------------------------------------------------ |--- Module : Data.Comp.MultiParam--- Copyright : (c) 2011 Patrick Bahr, Tom Hvitved--- License : BSD3--- Maintainer : Patrick Bahr <paba@diku.dk>, Tom Hvitved <hvitved@diku.dk>--- Stability : experimental--- Portability : non-portable (GHC Extensions)------ This module defines the infrastructure necessary to use--- /Generalised Parametric Compositional Data Types/. Generalised Parametric--- Compositional Data Types is an extension of Compositional Data Types with--- parametric higher-order abstract syntax (PHOAS) for usage with binders, and--- GADTs. Generalised Parametric Compositional Data Types combines Generalised--- Compositional Data Types ("Data.Comp.Multi") and Parametric Compositional--- Data Types ("Data.Comp.Param"). Examples of usage are bundled with the--- package in the library @examples\/Examples\/MultiParam@.-------------------------------------------------------------------------------------module Data.Comp.MultiParam (- module Data.Comp.MultiParam.Term- , module Data.Comp.MultiParam.Algebra- , module Data.Comp.MultiParam.HDifunctor- , module Data.Comp.MultiParam.Sum- , module Data.Comp.MultiParam.Annotation- , module Data.Comp.MultiParam.Equality- ) where--import Data.Comp.MultiParam.Term-import Data.Comp.MultiParam.Algebra-import Data.Comp.MultiParam.HDifunctor-import Data.Comp.MultiParam.Sum-import Data.Comp.MultiParam.Annotation-import Data.Comp.MultiParam.Equality
− src/Data/Comp/MultiParam/Algebra.hs
@@ -1,349 +0,0 @@-{-# LANGUAGE GADTs, Rank2Types, ScopedTypeVariables, TypeOperators,- FlexibleContexts, CPP, KindSignatures #-}------------------------------------------------------------------------------------ |--- Module : Data.Comp.MultiParam.Algebra--- Copyright : (c) 2011 Patrick Bahr, Tom Hvitved--- License : BSD3--- Maintainer : Tom Hvitved <hvitved@diku.dk>--- Stability : experimental--- Portability : non-portable (GHC Extensions)------ This module defines the notion of algebras and catamorphisms, and their--- generalizations to e.g. monadic versions and other (co)recursion schemes.--------------------------------------------------------------------------------------module Data.Comp.MultiParam.Algebra (- -- * Algebras & Catamorphisms- Alg,- free,- cata,- cata',- appCxt,- - -- * Monadic Algebras & Catamorphisms- AlgM,--- algM,- freeM,- cataM,- AlgM',- Compose(..),- freeM',- cataM',-- -- * Term Homomorphisms- CxtFun,- SigFun,- Hom,- appHom,- appHom',- compHom,- appSigFun,- appSigFun',- compSigFun,- hom,- compAlg,-- -- * Monadic Term Homomorphisms- CxtFunM,- SigFunM,- HomM,- sigFunM,- hom',- appHomM,- appTHomM,- appHomM',- appTHomM',- homM,- appSigFunM,- appTSigFunM,- appSigFunM',- appTSigFunM',- compHomM,- compSigFunM,- compAlgM,- compAlgM'- ) where--import Prelude hiding (sequence, mapM)-import Control.Monad hiding (sequence, mapM)-import Data.Functor.Compose -- Functor composition-import Data.Comp.MultiParam.Term-import Data.Comp.MultiParam.HDifunctor-import Data.Comp.MultiParam.HDitraversable--{-| This type represents an algebra over a difunctor @f@ and carrier @a@. -}-type Alg f a = f a a :-> a--{-| Construct a catamorphism for contexts over @f@ with holes of type @b@, from- the given algebra. -}-free :: forall h f a b. HDifunctor f- => Alg f a -> (b :-> a) -> Cxt h f a b :-> a-free f g = run- where run :: Cxt h f a b :-> a- run (In t) = f (hfmap run t)- run (Hole x) = g x- run (Var p) = p--{-| Construct a catamorphism from the given algebra. -}-cata :: forall f a. HDifunctor f => Alg f a -> Term f :-> a -{-# NOINLINE [1] cata #-}-cata f (Term t) = run t- where run :: Trm f a :-> a- run (In t) = f (hfmap run t)- run (Var x) = x--{-| A generalisation of 'cata' from terms over @f@ to contexts over @f@, where- the holes have the type of the algebra carrier. -}-cata' :: HDifunctor f => Alg f a -> Cxt h f a a :-> a-{-# INLINE cata' #-}-cata' f = free f id--{-| This function applies a whole context into another context. -}-appCxt :: HDifunctor f => Cxt Hole f a (Cxt h f a b) :-> Cxt h f a b-appCxt (In t) = In (hfmap appCxt t)-appCxt (Hole x) = x-appCxt (Var p) = Var p--{-| This type represents a monadic algebra. It is similar to 'Alg' but- the return type is monadic. -}-type AlgM m f a = NatM m (f a a) a--{-| Construct a monadic catamorphism for contexts over @f@ with holes of type- @b@, from the given monadic algebra. -}-freeM :: forall m h f a b. (HDitraversable f, Monad m)- => AlgM m f a -> NatM m b a -> NatM m (Cxt h f a b) a-freeM f g = run- where run :: NatM m (Cxt h f a b) a- run (In t) = f =<< hdimapM run t- run (Hole x) = g x- run (Var p) = return p--{-| Construct a monadic catamorphism from the given monadic algebra. -}-cataM :: forall m f a. (HDitraversable f, Monad m)- => AlgM m f a -> NatM m (Term f) a-{-# NOINLINE [1] cataM #-}-cataM algm (Term t) = run t- where run :: NatM m (Trm f a) a- run (In t) = algm =<< hdimapM run t- run (Var x) = return x--{-| This type represents a monadic algebra, but where the covariant argument is- also a monadic computation. -}-type AlgM' m f a = NatM m (f a (Compose m a)) a--{-| Construct a monadic catamorphism for contexts over @f@ with holes of type- @b@, from the given monadic algebra. -}-freeM' :: forall m h f a b. (HDifunctor f, Monad m)- => AlgM' m f a -> NatM m b a -> NatM m (Cxt h f a b) a-freeM' f g = run- where run :: NatM m (Cxt h f a b) a- run (In t) = f $ hfmap (Compose . run) t- run (Hole x) = g x- run (Var p) = return p--{-| Construct a monadic catamorphism from the given monadic algebra. -}-cataM' :: forall m f a. (HDifunctor f, Monad m)- => AlgM' m f a -> NatM m (Term f) a-{-# NOINLINE [1] cataM' #-}-cataM' algm (Term t) = run t- where run :: NatM m (Trm f a) a- run (In t) = algm $ hfmap (Compose . run) t- run (Var x) = return x--{-| This type represents a signature function. -}-type SigFun f g = forall (a :: * -> *) (b :: * -> *) . f a b :-> g a b--{-| This type represents a context function. -}-type CxtFun f g = forall h. SigFun (Cxt h f) (Cxt h g)--{-| This type represents a term homomorphism. -}-type Hom f g = SigFun f (Context g)--{-| Apply a term homomorphism recursively to a term/context. -}-appHom :: forall f g. (HDifunctor f, HDifunctor g) => Hom f g -> CxtFun f g-{-# INLINE [1] appHom #-}-appHom f = run where- run :: CxtFun f g- run (In t) = appCxt (f (hfmap run t))- run (Hole x) = Hole x- run (Var p) = Var p---- | Apply a term homomorphism recursively to a term/context. This is--- a top-down variant of 'appHom'.-appHom' :: forall f g. (HDifunctor g)- => Hom f g -> CxtFun f g-{-# INLINE [1] appHom' #-}-appHom' f = run where- run :: CxtFun f g- run (In t) = appCxt (hfmapCxt run (f t))- run (Hole x) = Hole x- run (Var p) = Var p--{-| Compose two term homomorphisms. -}-compHom :: (HDifunctor g, HDifunctor h)- => Hom g h -> Hom f g -> Hom f h-compHom f g = appHom f . g--{-| Compose an algebra with a term homomorphism to get a new algebra. -}-compAlg :: (HDifunctor f, HDifunctor g) => Alg g a -> Hom f g -> Alg f a-compAlg alg talg = cata' alg . talg--{-| This function applies a signature function to the given context. -}-appSigFun :: forall f g. (HDifunctor f) => SigFun f g -> CxtFun f g-appSigFun f = run where- run :: CxtFun f g- run (In t) = In (f (hfmap run t))- run (Hole x) = Hole x- run (Var p) = Var p--{-| This function applies a signature function to the given context. -}-appSigFun' :: forall f g. (HDifunctor g) => SigFun f g -> CxtFun f g-appSigFun' f = run where- run :: CxtFun f g- run (In t) = In (hfmap run (f t))- run (Hole x) = Hole x- run (Var p) = Var p--{-| This function composes two signature functions. -}-compSigFun :: SigFun g h -> SigFun f g -> SigFun f h-compSigFun f g = f . g--{-| Lifts the given signature function to the canonical term homomorphism. -}-hom :: HDifunctor g => SigFun f g -> Hom f g-hom f = simpCxt . f--{-| This type represents a monadic signature function. -}-type SigFunM m f g = forall (a :: * -> *) (b :: * -> *) . NatM m (f a b) (g a b)--{-| This type represents a monadic context function. -}-type CxtFunM m f g = forall h . SigFunM m (Cxt h f) (Cxt h g)--{-| This type represents a monadic term homomorphism. -}-type HomM m f g = SigFunM m f (Cxt Hole g)---{-| Lift the given signature function to a monadic signature function. Note that- term homomorphisms are instances of signature functions. Hence this function- also applies to term homomorphisms. -}-sigFunM :: Monad m => SigFun f g -> SigFunM m f g-sigFunM f = return . f--{-| Lift the give monadic signature function to a monadic term homomorphism. -}-hom' :: (HDifunctor f, HDifunctor g, Monad m)- => SigFunM m f g -> HomM m f g-hom' f = liftM (In . hfmap Hole) . f--{-| Lift the given signature function to a monadic term homomorphism. -}-homM :: (HDifunctor g, Monad m) => SigFun f g -> HomM m f g-homM f = sigFunM $ hom f--{-| Apply a monadic term homomorphism recursively to a term/context. -}-appHomM :: forall f g m. (HDitraversable f, Monad m, HDifunctor g)- => HomM m f g -> CxtFunM m f g-{-# NOINLINE [1] appHomM #-}-appHomM f = run- where run :: CxtFunM m f g- run (In t) = liftM appCxt (f =<< hdimapM run t)- run (Hole x) = return (Hole x)- run (Var p) = return (Var p)--{-| A restricted form of |appHomM| which only works for terms. -}-appTHomM :: (HDitraversable f, Monad m, ParamFunctor m, HDifunctor g)- => HomM m f g -> Term f i -> m (Term g i)-appTHomM f (Term t) = termM (appHomM f t)---- | Apply a monadic term homomorphism recursively to a--- term/context. This is a top-down variant of 'appHomM'.-appHomM' :: forall f g m. (HDitraversable g, Monad m)- => HomM m f g -> CxtFunM m f g-{-# NOINLINE [1] appHomM' #-}-appHomM' f = run- where run :: CxtFunM m f g- run (In t) = liftM appCxt (hdimapMCxt run =<< f t)- run (Hole x) = return (Hole x)- run (Var p) = return (Var p)--{-| A restricted form of |appHomM'| which only works for terms. -}-appTHomM' :: (HDitraversable g, Monad m, ParamFunctor m, HDifunctor g)- => HomM m f g -> Term f i -> m (Term g i)-appTHomM' f (Term t) = termM (appHomM' f t)--{-| This function applies a monadic signature function to the given context. -}-appSigFunM :: forall m f g. (HDitraversable f, Monad m)- => SigFunM m f g -> CxtFunM m f g-appSigFunM f = run- where run :: CxtFunM m f g- run (In t) = liftM In (f =<< hdimapM run t)- run (Hole x) = return (Hole x)- run (Var p) = return (Var p)--{-| A restricted form of |appSigFunM| which only works for terms. -}-appTSigFunM :: (HDitraversable f, Monad m, ParamFunctor m, HDifunctor g)- => SigFunM m f g -> Term f i -> m (Term g i)-appTSigFunM f (Term t) = termM (appSigFunM f t)---- | This function applies a monadic signature function to the given--- context. This is a top-down variant of 'appSigFunM'.-appSigFunM' :: forall m f g. (HDitraversable g, Monad m)- => SigFunM m f g -> CxtFunM m f g-appSigFunM' f = run- where run :: CxtFunM m f g- run (In t) = liftM In (hdimapM run =<< f t)- run (Hole x) = return (Hole x)- run (Var p) = return (Var p)--{-| A restricted form of |appSigFunM'| which only works for terms. -}-appTSigFunM' :: (HDitraversable g, Monad m, ParamFunctor m, HDifunctor g)- => SigFunM m f g -> Term f i -> m (Term g i)-appTSigFunM' f (Term t) = termM (appSigFunM' f t)--{-| Compose two monadic term homomorphisms. -}-compHomM :: (HDitraversable g, HDifunctor h, Monad m)- => HomM m g h -> HomM m f g -> HomM m f h-compHomM f g = appHomM f <=< g--{-| Compose a monadic algebra with a monadic term homomorphism to get a new- monadic algebra. -}-compAlgM :: (HDitraversable g, Monad m) => AlgM m g a -> HomM m f g -> AlgM m f a-compAlgM alg talg = freeM alg return <=< talg--{-| Compose a monadic algebra with a term homomorphism to get a new monadic- algebra. -}-compAlgM' :: (HDitraversable g, Monad m) => AlgM m g a -> Hom f g -> AlgM m f a-compAlgM' alg talg = freeM alg return . talg--{-| This function composes two monadic signature functions. -}-compSigFunM :: Monad m => SigFunM m g h -> SigFunM m f g -> SigFunM m f h-compSigFunM f g a = g a >>= f--{--#ifndef NO_RULES-{-# RULES- "cata/appHom" forall (a :: Alg g d) (h :: Hom f g) x.- cata a (appHom h x) = cata (compAlg a h) x;-- "appHom/appHom" forall (a :: Hom g h) (h :: Hom f g) x.- appHom a (appHom h x) = appHom (compHom a h) x;- #-}--{--{-# RULES - "cataM/appHomM" forall (a :: AlgM m g d) (h :: HomM m f g d) x.- appHomM h x >>= cataM a = cataM (compAlgM a h) x;-- "cataM/appHom" forall (a :: AlgM m g d) (h :: Hom f g) x.- cataM a (appHom h x) = cataM (compAlgM' a h) x;-- "appHomM/appHomM" forall (a :: HomM m g h b) (h :: HomM m f g b) x.- appHomM h x >>= appHomM a = appHomM (compHomM a h) x;- #-}--{-# RULES- "cata/build" forall alg (g :: forall a . Alg f a -> a) .- cata alg (build g) = g alg- #-}--}-#endif--}
− src/Data/Comp/MultiParam/Annotation.hs
@@ -1,80 +0,0 @@-{-# LANGUAGE TypeOperators, MultiParamTypeClasses, FlexibleInstances,- UndecidableInstances, Rank2Types, GADTs, ScopedTypeVariables #-}------------------------------------------------------------------------------------ |--- Module : Data.Comp.MultiParam.Annotation--- Copyright : (c) 2010-2011 Patrick Bahr, Tom Hvitved--- License : BSD3--- Maintainer : Tom Hvitved <hvitved@diku.dk>--- Stability : experimental--- Portability : non-portable (GHC Extensions)------ This module defines annotations on signatures.--------------------------------------------------------------------------------------module Data.Comp.MultiParam.Annotation- (- (:&:) (..),- (:*:) (..),- DistAnn (..),- RemA (..),- liftA,- liftA',- stripA,- propAnn,- propAnnM,- ann,- project'- ) where--import qualified Data.Comp.Ops as O-import Data.Comp.MultiParam.HDifunctor-import Data.Comp.MultiParam.Term-import Data.Comp.MultiParam.Sum-import Data.Comp.MultiParam.Ops-import Data.Comp.MultiParam.Algebra--import Control.Monad--{-| Transform a function with a domain constructed from a higher-order difunctor- to a function with a domain constructed with the same higher-order difunctor,- but with an additional annotation. -}-liftA :: (RemA s s') => (s' a b :-> t) -> s a b :-> t-liftA f v = f (remA v)--{-| Transform a function with a domain constructed from a higher-order difunctor- to a function with a domain constructed with the same higher-order difunctor,- but with an additional annotation. -}-liftA' :: (DistAnn s' p s, HDifunctor s')- => (s' a b :-> Cxt h s' c d) -> s a b :-> Cxt h s c d-liftA' f v = let v' O.:&: p = projectA v- in ann p (f v')--{-| Strip the annotations from a term over a higher-order difunctor with- annotations. -}-stripA :: (RemA g f, HDifunctor g) => CxtFun g f-stripA = appSigFun remA--{-| Lift a term homomorphism over signatures @f@ and @g@ to a term homomorphism- over the same signatures, but extended with annotations. -}-propAnn :: (DistAnn f p f', DistAnn g p g', HDifunctor g) - => Hom f g -> Hom f' g'-propAnn hom f' = ann p (hom f)- where f O.:&: p = projectA f'--{-| Lift a monadic term homomorphism over signatures @f@ and @g@ to a monadic- term homomorphism over the same signatures, but extended with annotations. -}-propAnnM :: (DistAnn f p f', DistAnn g p g', HDifunctor g, Monad m)- => HomM m f g -> HomM m f' g'-propAnnM hom f' = liftM (ann p) (hom f)- where f O.:&: p = projectA f'--{-| Annotate each node of a term with a constant value. -}-ann :: (DistAnn f p g, HDifunctor f) => p -> CxtFun f g-ann c = appSigFun (injectA c)--{-| This function is similar to 'project' but applies to signatures- with an annotation which is then ignored. -}-project' :: forall s s' f a b i h . (RemA s s', s :<: f) => Cxt h f a b i -> Maybe (s' a (Cxt h f a b) i)-project' v = liftM remA (project v :: Maybe (s a (Cxt h f a b) i))
− src/Data/Comp/MultiParam/Derive.hs
@@ -1,55 +0,0 @@-{-# LANGUAGE TemplateHaskell #-}------------------------------------------------------------------------------------ |--- Module : Data.Comp.MultiParam.Derive--- Copyright : (c) 2011 Patrick Bahr, Tom Hvitved--- License : BSD3--- Maintainer : Tom Hvitved <hvitved@diku.dk>--- Stability : experimental--- Portability : non-portable (GHC Extensions)------ This module contains functionality for automatically deriving boilerplate--- code using Template Haskell. Examples include instances of 'HDifunctor',--- 'ShowHD', and 'EqHD'.--------------------------------------------------------------------------------------module Data.Comp.MultiParam.Derive- (- derive,- -- |Derive boilerplate instances for parametric signatures, i.e.- -- signatures for parametric compositional data types.-- -- ** EqHD- module Data.Comp.MultiParam.Derive.Equality,- -- ** OrdHD- module Data.Comp.MultiParam.Derive.Ordering,- -- ** ShowHD- module Data.Comp.MultiParam.Derive.Show,- -- ** HDifunctor- module Data.Comp.MultiParam.Derive.HDifunctor,- -- ** Smart Constructors- module Data.Comp.MultiParam.Derive.SmartConstructors,- -- ** Smart Constructors w/ Annotations- module Data.Comp.MultiParam.Derive.SmartAConstructors,- -- ** Lifting to Sums- liftSum- ) where--import Data.Comp.Derive.Utils (derive, liftSumGen)-import Data.Comp.MultiParam.Derive.Equality-import Data.Comp.MultiParam.Derive.Ordering-import Data.Comp.MultiParam.Derive.Show-import Data.Comp.MultiParam.Derive.HDifunctor-import Data.Comp.MultiParam.Derive.SmartConstructors-import Data.Comp.MultiParam.Derive.SmartAConstructors-import Data.Comp.MultiParam.Ops ((:+:), caseHD)--import Language.Haskell.TH--{-| Given the name of a type class, where the first parameter is a higher-order- difunctor, lift it to sums of higher-order difunctors. Example:- @class ShowHD f where ...@ is lifted as- @instance (ShowHD f, ShowHD g) => ShowHD (f :+: g) where ... @. -}-liftSum :: Name -> Q [Dec]-liftSum = liftSumGen 'caseHD ''(:+:)
− src/Data/Comp/MultiParam/Derive/Equality.hs
@@ -1,78 +0,0 @@-{-# LANGUAGE TemplateHaskell, FlexibleInstances, IncoherentInstances,- ScopedTypeVariables #-}------------------------------------------------------------------------------------ |--- Module : Data.Comp.MultiParam.Derive.Equality--- Copyright : (c) 2011 Patrick Bahr, Tom Hvitved--- License : BSD3--- Maintainer : Tom Hvitved <hvitved@diku.dk>--- Stability : experimental--- Portability : non-portable (GHC Extensions)------ Automatically derive instances of @EqHD@.-------------------------------------------------------------------------------------module Data.Comp.MultiParam.Derive.Equality- (- EqHD(..),- makeEqHD- ) where--import Data.Comp.Derive.Utils-import Data.Comp.MultiParam.FreshM hiding (Name)-import Data.Comp.MultiParam.Equality-import Control.Monad-import Language.Haskell.TH hiding (Cxt, match)--{-| Derive an instance of 'EqHD' for a type constructor of any parametric- kind taking at least three arguments. -}-makeEqHD :: Name -> Q [Dec]-makeEqHD fname = do- TyConI (DataD _ name args constrs _) <- abstractNewtypeQ $ reify fname- let args' = init args- -- covariant argument- let coArg :: Name = tyVarBndrName $ last args'- -- contravariant argument- let conArg :: Name = tyVarBndrName $ last $ init args'- let argNames = map (VarT . tyVarBndrName) (init $ init args')- let complType = foldl AppT (ConT name) argNames- let classType = AppT (ConT ''EqHD) complType- constrs' :: [(Name,[Type])] <- mapM normalConExp constrs- let defC = if length constrs < 2 then- []- else- [clause [wildP,wildP] (normalB [|return False|]) []]- eqHDDecl <- funD 'eqHD (map (eqHDClause conArg coArg) constrs' ++ defC)- let context = map (\arg -> ClassP ''Eq [arg]) argNames- return [InstanceD context classType [eqHDDecl]]- where eqHDClause :: Name -> Name -> (Name,[Type]) -> ClauseQ- eqHDClause conArg coArg (constr, args) = do- varXs <- newNames (length args) "x"- varYs <- newNames (length args) "y"- -- Patterns for the constructors- let patx = ConP constr $ map VarP varXs- let paty = ConP constr $ map VarP varYs- body <- eqHDBody conArg coArg (zip3 varXs varYs args)- return $ Clause [patx,paty] (NormalB body) []- eqHDBody :: Name -> Name -> [(Name, Name, Type)] -> ExpQ- eqHDBody conArg coArg x =- [|liftM and (sequence $(listE $ map (eqHDB conArg coArg) x))|]- eqHDB :: Name -> Name -> (Name, Name, Type) -> ExpQ- eqHDB conArg coArg (x, y, tp)- | not (containsType tp (VarT conArg)) &&- not (containsType tp (VarT coArg)) =- [| return $ $(varE x) == $(varE y) |]- | otherwise =- case tp of- AppT (VarT a) _ - | a == coArg -> [| peq $(varE x) $(varE y) |]- AppT (AppT ArrowT (AppT (VarT a) _)) _- | a == conArg ->- [| withName (\v -> peq ($(varE x) $ nameCoerce v) ($(varE y) $ nameCoerce v)) |]- SigT tp' _ ->- eqHDB conArg coArg (x, y, tp')- _ ->- if containsType tp (VarT conArg) then- [| eqHD $(varE x) $(varE y) |]- else- [| peq $(varE x) $(varE y) |]
− src/Data/Comp/MultiParam/Derive/HDifunctor.hs
@@ -1,85 +0,0 @@-{-# LANGUAGE TemplateHaskell, ScopedTypeVariables #-}------------------------------------------------------------------------------------ |--- Module : Data.Comp.MultiParam.Derive.HDifunctor--- Copyright : (c) 2011 Patrick Bahr, Tom Hvitved--- License : BSD3--- Maintainer : Tom Hvitved <hvitved@diku.dk>--- Stability : experimental--- Portability : non-portable (GHC Extensions)------ Automatically derive instances of @HDifunctor@.--------------------------------------------------------------------------------------module Data.Comp.MultiParam.Derive.HDifunctor- (- HDifunctor,- makeHDifunctor- ) where--import Data.Comp.Derive.Utils-import Data.Comp.MultiParam.HDifunctor-import Language.Haskell.TH--{-| Derive an instance of 'HDifunctor' for a type constructor of any parametric- kind taking at least three arguments. -}-makeHDifunctor :: Name -> Q [Dec]-makeHDifunctor fname = do- TyConI (DataD _ name args constrs _) <- abstractNewtypeQ $ reify fname- let args' = init args- -- covariant argument- let coArg :: Name = tyVarBndrName $ last args'- -- contravariant argument- let conArg :: Name = tyVarBndrName $ last $ init args'- let argNames = map (VarT . tyVarBndrName) (init $ init args')- let complType = foldl AppT (ConT name) argNames- let classType = AppT (ConT ''HDifunctor) complType- constrs' :: [(Name,[Type])] <- mapM normalConExp constrs- hdimapDecl <- funD 'hdimap (map (hdimapClause conArg coArg) constrs')- return [InstanceD [] classType [hdimapDecl]]- where hdimapClause :: Name -> Name -> (Name,[Type]) -> ClauseQ- hdimapClause conArg coArg (constr, args) = do- fn <- newName "_f"- gn <- newName "_g"- varNs <- newNames (length args) "x"- let f = varE fn- let g = varE gn- let fp = VarP fn- let gp = VarP gn- -- Pattern for the constructor- let pat = ConP constr $ map VarP varNs- body <- hdimapArgs conArg coArg f g (zip varNs args) (conE constr)- return $ Clause [fp, gp, pat] (NormalB body) []- hdimapArgs :: Name -> Name -> ExpQ -> ExpQ- -> [(Name, Type)] -> ExpQ -> ExpQ- hdimapArgs _ _ _ _ [] acc =- acc- hdimapArgs conArg coArg f g ((x,tp):tps) acc =- hdimapArgs conArg coArg f g tps- (acc `appE` (hdimapArg conArg coArg tp f g `appE` varE x))- hdimapArg :: Name -> Name -> Type -> ExpQ -> ExpQ -> ExpQ- hdimapArg conArg coArg tp f g- | not (containsType tp (VarT conArg)) &&- not (containsType tp (VarT coArg)) = [| id |]- | otherwise =- case tp of- AppT (VarT a) _ | a == conArg -> f- | a == coArg -> g- AppT (AppT ArrowT tp1) tp2 -> do- xn <- newName "x"- let ftp1 = hdimapArg conArg coArg tp1 f g- let ftp2 = hdimapArg conArg coArg tp2 f g- lamE [varP xn]- (infixE (Just ftp2)- [|(.)|]- (Just $ infixE (Just $ varE xn)- [|(.)|]- (Just ftp1)))- SigT tp' _ ->- hdimapArg conArg coArg tp' f g- _ ->- if containsType tp (VarT conArg) then- [| hdimap $f $g |]- else- [| fmap $g |]
− src/Data/Comp/MultiParam/Derive/Injections.hs
@@ -1,91 +0,0 @@-{-# LANGUAGE TemplateHaskell #-}------------------------------------------------------------------------------------ |--- Module : Data.Comp.MultiParam.Derive.Injections--- Copyright : (c) 2011 Patrick Bahr, Tom Hvitved--- License : BSD3--- Maintainer : Tom Hvitved <hvitved@diku.dk>--- Stability : experimental--- Portability : non-portable (GHC Extensions)------ Derive functions for signature injections.--------------------------------------------------------------------------------------module Data.Comp.MultiParam.Derive.Injections- (- injn,- injectn,- deepInjectn- ) where--import Language.Haskell.TH hiding (Cxt)-import Data.Comp.MultiParam.HDifunctor-import Data.Comp.MultiParam.Term-import Data.Comp.MultiParam.Algebra (CxtFun, appSigFun)-import Data.Comp.MultiParam.Ops ((:+:)(..), (:<:)(..))--injn :: Int -> Q [Dec]-injn n = do- let i = mkName $ "inj" ++ show n- let fvars = map (\n -> mkName $ 'f' : show n) [1..n]- let gvar = mkName "g"- let avar = mkName "a"- let bvar = mkName "b"- let ivar = mkName "i"- let xvar = mkName "x"- let d = [funD i [clause [varP xvar] (normalB $ genDecl xvar n) []]]- sequence $ sigD i (genSig fvars gvar avar bvar ivar) : d- where genSig fvars gvar avar bvar ivar = do- let cxt = map (\f -> classP ''(:<:) [varT f, varT gvar]) fvars- let tp = foldl1 (\a f -> conT ''(:+:) `appT` f `appT` a)- (map varT fvars)- let tp' = arrowT `appT` (tp `appT` varT avar `appT`- varT bvar `appT` varT ivar)- `appT` (varT gvar `appT` varT avar `appT`- varT bvar `appT` varT ivar)- forallT (map PlainTV $ gvar : avar : bvar : ivar : fvars)- (sequence cxt) tp'- genDecl x n = [| case $(varE x) of- Inl x -> $(varE $ mkName "inj") x- Inr x -> $(varE $ mkName $ "inj" ++- if n > 2 then show (n - 1) else "") x |]-injectn :: Int -> Q [Dec]-injectn n = do- let i = mkName ("inject" ++ show n)- let fvars = map (\n -> mkName $ 'f' : show n) [1..n]- let gvar = mkName "g"- let avar = mkName "a"- let bvar = mkName "b"- let ivar = mkName "i"- let d = [funD i [clause [] (normalB $ genDecl n) []]]- sequence $ sigD i (genSig fvars gvar avar bvar ivar) : d- where genSig fvars gvar avar bvar ivar = do- let hvar = mkName "h"- let cxt = map (\f -> classP ''(:<:) [varT f, varT gvar]) fvars- let tp = foldl1 (\a f -> conT ''(:+:) `appT` f `appT` a)- (map varT fvars)- let tp' = conT ''Cxt `appT` varT hvar `appT` varT gvar- `appT` varT avar `appT` varT bvar- let tp'' = arrowT `appT` (tp `appT` varT avar `appT`- tp' `appT` varT ivar)- `appT` (tp' `appT` varT ivar)- forallT (map PlainTV $ hvar : gvar : avar : bvar : ivar : fvars)- (sequence cxt) tp''- genDecl n = [| In . $(varE $ mkName $ "inj" ++ show n) |]--deepInjectn :: Int -> Q [Dec]-deepInjectn n = do- let i = mkName ("deepInject" ++ show n)- let fvars = map (\n -> mkName $ 'f' : show n) [1..n]- let gvar = mkName "g"- let d = [funD i [clause [] (normalB $ genDecl n) []]]- sequence $ sigD i (genSig fvars gvar) : d- where genSig fvars gvar = do- let cxt = map (\f -> classP ''(:<:) [varT f, varT gvar]) fvars- let tp = foldl1 (\a f -> conT ''(:+:) `appT` f `appT` a)- (map varT fvars)- let cxt' = classP ''HDifunctor [tp]- let tp' = conT ''CxtFun `appT` tp `appT` varT gvar- forallT (map PlainTV $ gvar : fvars) (sequence $ cxt' : cxt) tp'- genDecl n = [| appSigFun $(varE $ mkName $ "inj" ++ show n) |]
− src/Data/Comp/MultiParam/Derive/Ordering.hs
@@ -1,93 +0,0 @@-{-# LANGUAGE TemplateHaskell, FlexibleInstances, IncoherentInstances,- ScopedTypeVariables #-}------------------------------------------------------------------------------------ |--- Module : Data.Comp.MultiParam.Derive.Ordering--- Copyright : (c) 2011 Patrick Bahr, Tom Hvitved--- License : BSD3--- Maintainer : Tom Hvitved <hvitved@diku.dk>--- Stability : experimental--- Portability : non-portable (GHC Extensions)------ Automatically derive instances of @OrdHD@.-------------------------------------------------------------------------------------module Data.Comp.MultiParam.Derive.Ordering- (- OrdHD(..),- makeOrdHD- ) where--import Data.Comp.MultiParam.FreshM hiding (Name)-import Data.Comp.MultiParam.Ordering-import Data.Comp.Derive.Utils-import Data.Maybe-import Data.List-import Language.Haskell.TH hiding (Cxt)-import Control.Monad (liftM)--compList :: [Ordering] -> Ordering-compList = fromMaybe EQ . find (/= EQ)--{-| Derive an instance of 'OrdHD' for a type constructor of any parametric- kind taking at least three arguments. -}-makeOrdHD :: Name -> Q [Dec]-makeOrdHD fname = do- TyConI (DataD _ name args constrs _) <- abstractNewtypeQ $ reify fname- let args' = init args- -- covariant argument- let coArg :: Name = tyVarBndrName $ last args'- -- contravariant argument- let conArg :: Name = tyVarBndrName $ last $ init args'- let argNames = map (VarT . tyVarBndrName) (init $ init args')- let complType = foldl AppT (ConT name) argNames- let classType = AppT (ConT ''OrdHD) complType- constrs' :: [(Name,[Type])] <- mapM normalConExp constrs- compareHDDecl <- funD 'compareHD (compareHDClauses conArg coArg constrs')- let context = map (\arg -> ClassP ''Ord [arg]) argNames- return [InstanceD context classType [compareHDDecl]]- where compareHDClauses :: Name -> Name -> [(Name,[Type])] -> [ClauseQ]- compareHDClauses _ _ [] = []- compareHDClauses conArg coArg constrs = - let constrs' = constrs `zip` [1..]- constPairs = [(x,y)| x<-constrs', y <- constrs']- in map (genClause conArg coArg) constPairs- genClause conArg coArg ((c,n),(d,m))- | n == m = genEqClause conArg coArg c- | n < m = genLtClause c d- | otherwise = genGtClause c d- genEqClause :: Name -> Name -> (Name,[Type]) -> ClauseQ- genEqClause conArg coArg (constr, args) = do - varXs <- newNames (length args) "x"- varYs <- newNames (length args) "y"- let patX = ConP constr $ map VarP varXs- let patY = ConP constr $ map VarP varYs- body <- eqDBody conArg coArg (zip3 varXs varYs args)- return $ Clause [patX, patY] (NormalB body) []- eqDBody :: Name -> Name -> [(Name, Name, Type)] -> ExpQ- eqDBody conArg coArg x =- [|liftM compList (sequence $(listE $ map (eqDB conArg coArg) x))|]- eqDB :: Name -> Name -> (Name, Name, Type) -> ExpQ- eqDB conArg coArg (x, y, tp)- | not (containsType tp (VarT conArg)) &&- not (containsType tp (VarT coArg)) =- [| return $ compare $(varE x) $(varE y) |]- | otherwise =- case tp of- AppT (VarT a) _ - | a == coArg -> [| pcompare $(varE x) $(varE y) |]- AppT (AppT ArrowT (AppT (VarT a) _)) _- | a == conArg ->- [| withName (\v -> pcompare ($(varE x) $ nameCoerce v)- ($(varE y) $ nameCoerce v)) |]- SigT tp' _ ->- eqDB conArg coArg (x, y, tp')- _ ->- if containsType tp (VarT conArg) then- [| compareHD $(varE x) $(varE y) |]- else- [| pcompare $(varE x) $(varE y) |]- genLtClause (c, _) (d, _) =- clause [recP c [], recP d []] (normalB [| return LT |]) []- genGtClause (c, _) (d, _) =- clause [recP c [], recP d []] (normalB [| return GT |]) []
− src/Data/Comp/MultiParam/Derive/Projections.hs
@@ -1,108 +0,0 @@-{-# LANGUAGE TemplateHaskell, GADTs #-}------------------------------------------------------------------------------------ |--- Module : Data.Comp.MultiParam.Derive.Projections--- Copyright : (c) 2011 Patrick Bahr, Tom Hvitved--- License : BSD3--- Maintainer : Tom Hvitved <hvitved@diku.dk>--- Stability : experimental--- Portability : non-portable (GHC Extensions)------ Derive functions for signature projections.--------------------------------------------------------------------------------------module Data.Comp.MultiParam.Derive.Projections- (- projn,- projectn,- deepProjectn- ) where--import Language.Haskell.TH hiding (Cxt)-import Control.Monad (liftM)-import Data.Comp.MultiParam.HDitraversable (HDitraversable)-import Data.Comp.MultiParam.Term-import Data.Comp.MultiParam.Algebra (appTSigFunM')-import Data.Comp.MultiParam.Ops ((:+:)(..), (:<:)(..))--projn :: Int -> Q [Dec]-projn n = do- let p = mkName $ "proj" ++ show n- let gvars = map (\n -> mkName $ 'g' : show n) [1..n]- let avar = mkName "a"- let bvar = mkName "b"- let ivar = mkName "i"- let xvar = mkName "x"- let d = [funD p [clause [varP xvar] (normalB $ genDecl xvar gvars avar bvar ivar) []]]- sequence $ (sigD p $ genSig gvars avar bvar ivar) : d- where genSig gvars avar bvar ivar = do- let fvar = mkName "f"- let cxt = map (\g -> classP ''(:<:) [varT g, varT fvar]) gvars- let tp = foldl1 (\a g -> conT ''(:+:) `appT` g `appT` a)- (map varT gvars)- let tp' = arrowT `appT` (varT fvar `appT` varT avar `appT`- varT bvar `appT` varT ivar)- `appT` (conT ''Maybe `appT`- (tp `appT` varT avar `appT`- varT bvar `appT` varT ivar))- forallT (map PlainTV $ fvar : avar : bvar : ivar : gvars)- (sequence cxt) tp'- genDecl x [g] a b i =- [| liftM inj (proj $(varE x)- :: Maybe ($(varT g `appT` varT a `appT`- varT b `appT` varT i))) |]- genDecl x (g:gs) a b i =- [| case (proj $(varE x)- :: Maybe ($(varT g `appT` varT a `appT`- varT b `appT` varT i))) of- Just y -> Just $ inj y- _ -> $(genDecl x gs a b i) |]- genDecl _ _ _ _ _ = error "genDecl called with empty list"--projectn :: Int -> Q [Dec]-projectn n = do- let p = mkName ("project" ++ show n)- let gvars = map (\n -> mkName $ 'g' : show n) [1..n]- let avar = mkName "a"- let bvar = mkName "b"- let ivar = mkName "i"- let xvar = mkName "x"- let d = [funD p [clause [varP xvar] (normalB $ genDecl xvar n) []]]- sequence $ (sigD p $ genSig gvars avar bvar ivar) : d- where genSig gvars avar bvar ivar = do- let fvar = mkName "f"- let hvar = mkName "h"- let cxt = map (\g -> classP ''(:<:) [varT g, varT fvar]) gvars- let tp = foldl1 (\a g -> conT ''(:+:) `appT` g `appT` a)- (map varT gvars)- let tp' = conT ''Cxt `appT` varT hvar `appT` varT fvar- `appT` varT avar `appT` varT bvar- let tp'' = arrowT `appT` (tp' `appT` varT ivar)- `appT` (conT ''Maybe `appT`- (tp `appT` varT avar `appT` tp' `appT`- varT ivar))- forallT (map PlainTV $ hvar : fvar : avar : bvar : ivar : gvars)- (sequence cxt) tp''- genDecl x n = [| case $(varE x) of- Hole _ -> Nothing- Var _ -> Nothing- In t -> $(varE $ mkName $ "proj" ++ show n) t |]--deepProjectn :: Int -> Q [Dec]-deepProjectn n = do- let p = mkName ("deepProject" ++ show n)- let gvars = map (\n -> mkName $ 'g' : show n) [1..n]- let d = [funD p [clause [] (normalB $ genDecl n) []]]- sequence $ (sigD p $ genSig gvars) : d- where genSig gvars = do- let fvar = mkName "f"- let ivar = mkName "i"- let cxt = map (\g -> classP ''(:<:) [varT g, varT fvar]) gvars- let tp = foldl1 (\a g -> conT ''(:+:) `appT` g `appT` a)- (map varT gvars)- let cxt' = classP ''HDitraversable [tp]- let tp' = arrowT `appT` (conT ''Term `appT` varT fvar `appT` varT ivar)- `appT` (conT ''Maybe `appT` (conT ''Term `appT` tp `appT` varT ivar))- forallT (map PlainTV $ fvar : ivar : gvars) (sequence $ cxt' : cxt) tp'- genDecl n = [| appTSigFunM' $(varE $ mkName $ "proj" ++ show n) |]
− src/Data/Comp/MultiParam/Derive/Show.hs
@@ -1,87 +0,0 @@-{-# LANGUAGE TemplateHaskell, FlexibleInstances, IncoherentInstances,- ScopedTypeVariables, UndecidableInstances, KindSignatures #-}------------------------------------------------------------------------------------ |--- Module : Data.Comp.MultiParam.Derive.Show--- Copyright : (c) 2011 Patrick Bahr, Tom Hvitved--- License : BSD3--- Maintainer : Tom Hvitved <hvitved@diku.dk>--- Stability : experimental--- Portability : non-portable (GHC Extensions)------ Automatically derive instances of @ShowHD@.-------------------------------------------------------------------------------------module Data.Comp.MultiParam.Derive.Show- (- ShowHD(..),- makeShowHD- ) where--import Data.Comp.Derive.Utils-import Data.Comp.MultiParam.FreshM hiding (Name)-import qualified Data.Comp.MultiParam.FreshM as FreshM-import Data.Comp.MultiParam.HDifunctor-import Control.Monad-import Language.Haskell.TH hiding (Cxt, match)-import qualified Data.Traversable as T--{-| Signature printing. An instance @ShowHD f@ gives rise to an instance- @Show (Term f i)@. -}-class ShowHD f where- showHD :: f FreshM.Name (K (FreshM String)) i -> FreshM String--newtype Dummy = Dummy String--instance Show Dummy where- show (Dummy s) = s--{-| Derive an instance of 'ShowHD' for a type constructor of any parametric- kind taking at least three arguments. -}-makeShowHD :: Name -> Q [Dec]-makeShowHD fname = do- TyConI (DataD _ name args constrs _) <- abstractNewtypeQ $ reify fname- let args' = init args- -- covariant argument- let coArg :: Name = tyVarBndrName $ last args'- -- contravariant argument- let conArg :: Name = tyVarBndrName $ last $ init args'- let argNames = map (VarT . tyVarBndrName) (init $ init args')- let complType = foldl AppT (ConT name) argNames- let classType = AppT (ConT ''ShowHD) complType- constrs' :: [(Name,[Type])] <- mapM normalConExp constrs- showHDDecl <- funD 'showHD (map (showHDClause conArg coArg) constrs')- let context = map (\arg -> ClassP ''Show [arg]) argNames- return [InstanceD context classType [showHDDecl]]- where showHDClause :: Name -> Name -> (Name,[Type]) -> ClauseQ- showHDClause conArg coArg (constr, args) = do- varXs <- newNames (length args) "x"- -- Pattern for the constructor- let patx = ConP constr $ map VarP varXs- body <- showHDBody (nameBase constr) conArg coArg (zip varXs args)- return $ Clause [patx] (NormalB body) []- showHDBody :: String -> Name -> Name -> [(Name, Type)] -> ExpQ- showHDBody constr conArg coArg x =- [|liftM (unwords . (constr :) .- map (\x -> if elem ' ' x then "(" ++ x ++ ")" else x))- (sequence $(listE $ map (showHDB conArg coArg) x))|]- showHDB :: Name -> Name -> (Name, Type) -> ExpQ- showHDB conArg coArg (x, tp)- | not (containsType tp (VarT conArg)) &&- not (containsType tp (VarT coArg)) =- [| return $ show $(varE x) |]- | otherwise =- case tp of- AppT (VarT a) _ - | a == coArg -> [| unK $(varE x) |]- AppT (AppT ArrowT (AppT (VarT a) _)) _- | a == conArg ->- [| withName (\v -> do body <- (unK . $(varE x)) v- return $ "\\" ++ show v ++ " -> " ++ body) |]- SigT tp' _ ->- showHDB conArg coArg (x, tp')- _ ->- if containsType tp (VarT conArg) then- [| showHD $(varE x) |]- else- [| liftM show $ T.mapM (liftM Dummy . unK) $(varE x) |]
− src/Data/Comp/MultiParam/Derive/SmartAConstructors.hs
@@ -1,48 +0,0 @@-{-# LANGUAGE TemplateHaskell #-}------------------------------------------------------------------------------------ |--- Module : Data.Comp.MultiParam.Derive.SmartAConstructors--- Copyright : (c) 2011 Patrick Bahr, Tom Hvitved--- License : BSD3--- Maintainer : Tom Hvitved <hvitved@diku.dk>--- Stability : experimental--- Portability : non-portable (GHC Extensions)------ Automatically derive smart constructors with annotations for higher-order--- difunctors.--------------------------------------------------------------------------------------module Data.Comp.MultiParam.Derive.SmartAConstructors - (- smartAConstructors- ) where--import Language.Haskell.TH hiding (Cxt)-import Data.Comp.Derive.Utils-import Data.Comp.MultiParam.Ops-import Data.Comp.MultiParam.Term-import Data.Comp.MultiParam.HDifunctor--import Control.Monad--{-| Derive smart constructors with annotations for a higher-order difunctor. The- smart constructors are similar to the ordinary constructors, but a- 'injectA . hdimap Var id' is automatically inserted. -}-smartAConstructors :: Name -> Q [Dec]-smartAConstructors fname = do- TyConI (DataD _cxt tname targs constrs _deriving) <- abstractNewtypeQ $ reify fname- let cons = map abstractConType constrs- liftM concat $ mapM (genSmartConstr (map tyVarBndrName targs) tname) cons- where genSmartConstr targs tname (name, args) = do- let bname = nameBase name- genSmartConstr' targs tname (mkName $ "iA" ++ bname) name args- genSmartConstr' targs tname sname name args = do- varNs <- newNames args "x"- varPr <- newName "_p"- let pats = map varP (varPr : varNs)- vars = map varE varNs- val = appE [|injectA $(varE varPr)|] $- appE [|inj . hdimap Var id|] $ foldl appE (conE name) vars- function = [funD sname [clause pats (normalB [|In $val|]) []]]- sequence function
− src/Data/Comp/MultiParam/Derive/SmartConstructors.hs
@@ -1,72 +0,0 @@-{-# LANGUAGE TemplateHaskell #-}------------------------------------------------------------------------------------ |--- Module : Data.Comp.MultiParam.Derive.SmartConstructors--- Copyright : (c) 2011 Patrick Bahr, Tom Hvitved--- License : BSD3--- Maintainer : Tom Hvitved <hvitved@diku.dk>--- Stability : experimental--- Portability : non-portable (GHC Extensions)------ Automatically derive smart constructors for higher-order difunctors.--------------------------------------------------------------------------------------module Data.Comp.MultiParam.Derive.SmartConstructors - (- smartConstructors- ) where--import Language.Haskell.TH hiding (Cxt)-import Data.Comp.Derive.Utils-import Data.Comp.MultiParam.Sum-import Data.Comp.MultiParam.Term-import Data.Comp.MultiParam.HDifunctor-import Control.Arrow ((&&&))-import Control.Monad--{-| Derive smart constructors for a higher-order difunctor. The smart- constructors are similar to the ordinary constructors, but a- 'inject . hdimap Var id' is automatically inserted. -}-smartConstructors :: Name -> Q [Dec]-smartConstructors fname = do- TyConI (DataD _cxt tname targs constrs _deriving) <- abstractNewtypeQ $ reify fname- let iVar = tyVarBndrName $ last targs- let cons = map (abstractConType &&& iTp iVar) constrs- liftM concat $ mapM (genSmartConstr (map tyVarBndrName targs) tname) cons- where iTp iVar (ForallC _ cxt _) =- -- Check if the GADT phantom type is constrained- case [y | EqualP x y <- cxt, x == VarT iVar] of- [] -> Nothing- tp:_ -> Just tp- iTp _ _ = Nothing- genSmartConstr targs tname ((name, args), miTp) = do- let bname = nameBase name- genSmartConstr' targs tname (mkName $ 'i' : bname) name args miTp- genSmartConstr' targs tname sname name args miTp = do- varNs <- newNames args "x"- let pats = map varP varNs- vars = map varE varNs- val = foldl appE (conE name) vars- sig = genSig targs tname sname args miTp- function = [funD sname [clause pats (normalB [|inject (hdimap Var id $val)|]) []]]- sequence $ sig ++ function- genSig targs tname sname 0 miTp = (:[]) $ do- hvar <- newName "h"- fvar <- newName "f"- avar <- newName "a"- bvar <- newName "b"- ivar <- newName "i"- let targs' = init $ init $ init targs- vars = hvar:fvar:avar:bvar:maybe [ivar] (const []) miTp++targs'- h = varT hvar- f = varT fvar- a = varT avar- b = varT bvar- i = varT ivar- ftype = foldl appT (conT tname) (map varT targs')- constr = classP ''(:<:) [ftype, f]- typ = foldl appT (conT ''Cxt) [h, f, a, b,maybe i return miTp]- typeSig = forallT (map PlainTV vars) (sequence [constr]) typ- sigD sname typeSig- genSig _ _ _ _ _ = []
− src/Data/Comp/MultiParam/Desugar.hs
@@ -1,44 +0,0 @@-{-# LANGUAGE TemplateHaskell, MultiParamTypeClasses, FlexibleInstances,- UndecidableInstances, OverlappingInstances, TypeOperators, Rank2Types #-}------------------------------------------------------------------------------------ |--- Module : Data.Comp.MultiParam.Desugar--- Copyright : (c) 2011 Patrick Bahr, Tom Hvitved--- License : BSD3--- Maintainer : Tom Hvitved <hvitved@diku.dk>--- Stability : experimental--- Portability : non-portable (GHC Extensions)------ This modules defines the 'Desugar' type class for desugaring of terms.--------------------------------------------------------------------------------------module Data.Comp.MultiParam.Desugar where--import Data.Comp.MultiParam---- |The desugaring term homomorphism.-class (HDifunctor f, HDifunctor g) => Desugar f g where- desugHom :: Hom f g- desugHom = desugHom' . hfmap Hole- desugHom' :: f a (Cxt h g a b) :-> Cxt h g a b- desugHom' x = appCxt (desugHom x)---- We make the lifting to sums explicit in order to make the Desugar--- class work with the default instance declaration further below.-instance (Desugar f h, Desugar g h) => Desugar (f :+: g) h where- desugHom = caseHD desugHom desugHom----- |Desugar a term.-desugar :: Desugar f g => Term f :-> Term g-desugar (Term t) = Term (appHom desugHom t)---- |Lift desugaring to annotated terms.-desugarA :: (HDifunctor f', HDifunctor g', DistAnn f p f', DistAnn g p g',- Desugar f g) => Term f' :-> Term g'-desugarA (Term t) = Term (appHom (propAnn desugHom) t)---- |Default desugaring instance.-instance (HDifunctor f, HDifunctor g, f :<: g) => Desugar f g where- desugHom = simpCxt . inj
− src/Data/Comp/MultiParam/Equality.hs
@@ -1,64 +0,0 @@-{-# LANGUAGE TypeOperators, TypeSynonymInstances, FlexibleInstances,- UndecidableInstances, IncoherentInstances, GADTs #-}------------------------------------------------------------------------------------ |--- Module : Data.Comp.MultiParam.Equality--- Copyright : (c) 2011 Patrick Bahr, Tom Hvitved--- License : BSD3--- Maintainer : Tom Hvitved <hvitved@diku.dk>--- Stability : experimental--- Portability : non-portable (GHC Extensions)------ This module defines equality for signatures, which lifts to equality for--- terms.-------------------------------------------------------------------------------------module Data.Comp.MultiParam.Equality- (- PEq(..),- EqHD(..)- ) where--import Data.Comp.MultiParam.Term-import Data.Comp.MultiParam.Sum-import Data.Comp.MultiParam.Ops-import Data.Comp.MultiParam.HDifunctor-import Data.Comp.MultiParam.FreshM---- |Equality on parametric values. The equality test is performed inside the--- 'FreshM' monad for generating fresh identifiers.-class PEq a where- peq :: a i -> a j -> FreshM Bool--instance Eq a => PEq (K a) where- peq (K x) (K y) = return $ x == y--{-| Signature equality. An instance @EqHD f@ gives rise to an instance- @Eq (Term f i)@. The equality test is performed inside the 'FreshM' monad for- generating fresh identifiers. -}-class EqHD f where- eqHD :: PEq a => f Name a i -> f Name a j -> FreshM Bool--{-| 'EqHD' is propagated through sums. -}-instance (EqHD f, EqHD g) => EqHD (f :+: g) where- eqHD (Inl x) (Inl y) = eqHD x y- eqHD (Inr x) (Inr y) = eqHD x y- eqHD _ _ = return False--instance PEq Name where- peq x y = return $ nameCoerce x == y--{-| From an 'EqHD' difunctor an 'Eq' instance of the corresponding term type can- be derived. -}-instance EqHD f => EqHD (Cxt h f) where- eqHD (In e1) (In e2) = eqHD e1 e2- eqHD (Hole h1) (Hole h2) = peq h1 h2- eqHD (Var p1) (Var p2) = peq p1 p2- eqHD _ _ = return False--instance (EqHD f, PEq a) => PEq (Cxt h f Name a) where- peq = eqHD--{-| Equality on terms. -}-instance (HDifunctor f, EqHD f) => Eq (Term f i) where- (==) (Term x) (Term y) = evalFreshM $ eqHD x y
− src/Data/Comp/MultiParam/FreshM.hs
@@ -1,54 +0,0 @@-{-# LANGUAGE GeneralizedNewtypeDeriving #-}------------------------------------------------------------------------------------ |--- Module : Data.Comp.MultiParam.FreshM--- Copyright : (c) 2011 Patrick Bahr, Tom Hvitved--- License : BSD3--- Maintainer : Tom Hvitved <hvitved@diku.dk>--- Stability : experimental--- Portability : non-portable (GHC Extensions)------ This module defines a monad for generating fresh, abstract names, useful--- e.g. for defining equality on terms.-------------------------------------------------------------------------------------module Data.Comp.MultiParam.FreshM- (- FreshM,- Name,- withName,- nameCoerce,- evalFreshM- ) where--import Control.Monad.Reader---- |Monad for generating fresh (abstract) names.-newtype FreshM a = FreshM{unFreshM :: Reader Int a}- deriving Monad---- |Abstract notion of a name (the constructor is hidden).-newtype Name i = Name Int- deriving Eq--instance Show (Name i) where- show (Name x) = names !! x- where baseNames = ['a'..'z']- names = map (:[]) baseNames ++ names' 1- names' n = map (: show n) baseNames ++ names' (n + 1)--instance Ord (Name i) where- compare (Name x) (Name y) = compare x y---- |Change the type tag of a name.-nameCoerce :: Name i -> Name j-nameCoerce (Name x) = Name x---- |Run the given computation with the next available name.-withName :: (Name i -> FreshM a) -> FreshM a-withName m = do name <- FreshM (asks Name)- FreshM $ local ((+) 1) $ unFreshM $ m name---- |Evaluate a computation that uses fresh names.-evalFreshM :: FreshM a -> a-evalFreshM (FreshM m) = runReader m 0
− src/Data/Comp/MultiParam/HDifunctor.hs
@@ -1,40 +0,0 @@-{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances, Rank2Types,- TypeOperators, GADTs #-}------------------------------------------------------------------------------------ |--- Module : Data.Comp.MultiParam.HDifunctor--- Copyright : (c) 2011 Patrick Bahr, Tom Hvitved--- License : BSD3--- Maintainer : Tom Hvitved <hvitved@diku.dk>--- Stability : experimental--- Portability : non-portable (GHC Extensions)------ This module defines higher-order difunctors, a hybrid between higher-order--- functors (Johann, Ghani, POPL '08), and difunctors (Meijer, Hutton, FPCA--- '95). Higher-order difunctors are used to define signatures for--- compositional parametric generalised data types.--------------------------------------------------------------------------------------module Data.Comp.MultiParam.HDifunctor- (- HDifunctor (..),- HFunctor (..),- I (..),- K (..),- E (..),- A (..),- (:->),- NatM- ) where--import Data.Comp.Multi.HFunctor---- | This class represents higher-order difunctors.-class HDifunctor f where- hdimap :: (a :-> b) -> (c :-> d) -> f b c :-> f a d---- |A higher-order difunctor gives rise to a higher-order functor when--- restricted to a particular contravariant argument.-instance HDifunctor f => HFunctor (f a) where- hfmap = hdimap id
− src/Data/Comp/MultiParam/HDitraversable.hs
@@ -1,29 +0,0 @@-{-# LANGUAGE Rank2Types, FlexibleInstances, MultiParamTypeClasses,- FlexibleContexts, OverlappingInstances, TypeOperators, GADTs #-}------------------------------------------------------------------------------------ |--- Module : Data.Comp.MultiParam.HDitraversable--- Copyright : (c) 2011 Patrick Bahr, Tom Hvitved--- License : BSD3--- Maintainer : Tom Hvitved <hvitved@diku.dk>--- Stability : experimental--- Portability : non-portable (GHC Extensions)------ This module defines traversable higher-order difunctors.--------------------------------------------------------------------------------------module Data.Comp.MultiParam.HDitraversable- (- HDitraversable (..),- HTraversable (..)- ) where--import Prelude hiding (mapM, sequence, foldr)-import Data.Comp.Multi.HTraversable-import Data.Comp.MultiParam.HDifunctor--{-| HDifunctors representing data structures that can be traversed from left to- right. -}-class HDifunctor f => HDitraversable f where- hdimapM :: Monad m => NatM m b c -> NatM m (f a b) (f a c)
− src/Data/Comp/MultiParam/Ops.hs
@@ -1,126 +0,0 @@-{-# LANGUAGE TypeOperators, MultiParamTypeClasses, FunctionalDependencies,- FlexibleInstances, UndecidableInstances, IncoherentInstances,- KindSignatures, RankNTypes #-}------------------------------------------------------------------------------------ |--- Module : Data.Comp.MultiParam.Ops--- Copyright : (c) 2011 Patrick Bahr, Tom Hvitved--- License : BSD3--- Maintainer : Tom Hvitved <hvitved@diku.dk>--- Stability : experimental--- Portability : non-portable (GHC Extensions)------ This module provides operators on higher-order difunctors.--------------------------------------------------------------------------------------module Data.Comp.MultiParam.Ops where--import Data.Comp.MultiParam.HDifunctor-import Data.Comp.MultiParam.HDitraversable-import qualified Data.Comp.Ops as O-import Control.Monad (liftM)----- Sums-infixr 6 :+:---- |Formal sum of signatures (difunctors).-data (f :+: g) (a :: * -> *) (b :: * -> *) i = Inl (f a b i)- | Inr (g a b i)--{-| Utility function to case on a higher-order difunctor sum, without exposing- the internal representation of sums. -}-caseHD :: (f a b i -> c) -> (g a b i -> c) -> (f :+: g) a b i -> c-caseHD f g x = case x of- Inl x -> f x- Inr x -> g x--instance (HDifunctor f, HDifunctor g) => HDifunctor (f :+: g) where- hdimap f g (Inl e) = Inl (hdimap f g e)- hdimap f g (Inr e) = Inr (hdimap f g e)--instance (HDitraversable f, HDitraversable g) => HDitraversable (f :+: g) where- hdimapM f (Inl e) = Inl `liftM` hdimapM f e- hdimapM f (Inr e) = Inr `liftM` hdimapM f e---- | Signature containment relation for automatic injections. The left-hand must--- be an atomic signature, where as the right-hand side must have a list-like--- structure. Examples include @f :<: f :+: g@ and @g :<: f :+: (g :+: h)@,--- non-examples include @f :+: g :<: f :+: (g :+: h)@ and--- @f :<: (f :+: g) :+: h@.-class (sub :: (* -> *) -> (* -> *) -> * -> *) :<: sup where- inj :: sub a b :-> sup a b- proj :: NatM Maybe (sup a b) (sub a b)--instance (:<:) f f where- inj = id- proj = Just--instance (:<:) f (f :+: g) where- inj = Inl- proj (Inl x) = Just x- proj (Inr _) = Nothing--instance (f :<: g) => (:<:) f (h :+: g) where- inj = Inr . inj- proj (Inr x) = proj x- proj (Inl _) = Nothing----- Products-infixr 8 :*:---- |Formal product of signatures (higher-order difunctors).-data (f :*: g) a b = f a b :*: g a b--ffst :: (f :*: g) a b -> f a b-ffst (x :*: _) = x--fsnd :: (f :*: g) a b -> g a b -fsnd (_ :*: x) = x----- Constant Products-infixr 7 :&:--{-| This data type adds a constant product to a signature. -}-data (f :&: p) (a :: * -> *) (b :: * -> *) i = f a b i :&: p--instance HDifunctor f => HDifunctor (f :&: p) where- hdimap f g (v :&: c) = hdimap f g v :&: c--instance HDitraversable f => HDitraversable (f :&: p) where- hdimapM f (v :&: c) = liftM (:&: c) (hdimapM f v)--{-| This class defines how to distribute an annotation over a sum of- signatures. -}-class DistAnn (s :: (* -> *) -> (* -> *) -> * -> *) p s' | s' -> s, s' -> p where- {-| Inject an annotation over a signature. -}- injectA :: p -> s a b :-> s' a b- {-| Project an annotation from a signature. -}- projectA :: s' a b :-> (s a b O.:&: p)--class RemA (s :: (* -> *) -> (* -> *) -> * -> *) s' | s -> s' where- {-| Remove annotations from a signature. -}- remA :: s a b :-> s' a b--instance (RemA s s') => RemA (f :&: p :+: s) (f :+: s') where- remA (Inl (v :&: _)) = Inl v- remA (Inr v) = Inr $ remA v--instance RemA (f :&: p) f where- remA (v :&: _) = v--instance DistAnn f p (f :&: p) where- injectA c v = v :&: c-- projectA (v :&: p) = v O.:&: p--instance (DistAnn s p s') => DistAnn (f :+: s) p ((f :&: p) :+: s') where- injectA c (Inl v) = Inl (v :&: c)- injectA c (Inr v) = Inr $ injectA c v-- projectA (Inl (v :&: p)) = Inl v O.:&: p- projectA (Inr v) = let (v' O.:&: p) = projectA v- in Inr v' O.:&: p
− src/Data/Comp/MultiParam/Ordering.hs
@@ -1,67 +0,0 @@-{-# LANGUAGE TypeOperators, TypeSynonymInstances, FlexibleInstances,- UndecidableInstances, IncoherentInstances, GADTs #-}------------------------------------------------------------------------------------ |--- Module : Data.Comp.MultiParam.Ordering--- Copyright : (c) 2011 Patrick Bahr, Tom Hvitved--- License : BSD3--- Maintainer : Tom Hvitved <hvitved@diku.dk>--- Stability : experimental--- Portability : non-portable (GHC Extensions)------ This module defines ordering of signatures, which lifts to ordering of--- terms and contexts.-------------------------------------------------------------------------------------module Data.Comp.MultiParam.Ordering- (- POrd(..),- OrdHD(..)- ) where--import Data.Comp.MultiParam.Term-import Data.Comp.MultiParam.Sum-import Data.Comp.MultiParam.Ops-import Data.Comp.MultiParam.HDifunctor-import Data.Comp.MultiParam.FreshM-import Data.Comp.MultiParam.Equality---- |Ordering of parametric values.-class PEq a => POrd a where- pcompare :: a i -> a j -> FreshM Ordering--instance Ord a => POrd (K a) where- pcompare (K x) (K y) = return $ compare x y--{-| Signature ordering. An instance @OrdHD f@ gives rise to an instance- @Ord (Term f)@. -}-class EqHD f => OrdHD f where- compareHD :: POrd a => f Name a i -> f Name a j -> FreshM Ordering--{-| 'OrdHD' is propagated through sums. -}-instance (OrdHD f, OrdHD g) => OrdHD (f :+: g) where- compareHD (Inl x) (Inl y) = compareHD x y- compareHD (Inl _) (Inr _) = return LT- compareHD (Inr x) (Inr y) = compareHD x y- compareHD (Inr _) (Inl _) = return GT--{-| From an 'OrdHD' difunctor an 'Ord' instance of the corresponding term type- can be derived. -}-instance OrdHD f => OrdHD (Cxt h f) where- compareHD (In e1) (In e2) = compareHD e1 e2- compareHD (Hole h1) (Hole h2) = pcompare h1 h2- compareHD (Var p1) (Var p2) = pcompare p1 p2- compareHD (In _) _ = return LT- compareHD (Hole _) (In _) = return GT- compareHD (Hole _) (Var _) = return LT- compareHD (Var _) _ = return GT--instance POrd Name where- pcompare x y = return $ compare (nameCoerce x) y--instance (OrdHD f, POrd a) => POrd (Cxt h f Name a) where- pcompare = compareHD--{-| Ordering of terms. -}-instance (HDifunctor f, OrdHD f) => Ord (Term f i) where- compare (Term x) (Term y) = evalFreshM $ compareHD x y
− src/Data/Comp/MultiParam/Show.hs
@@ -1,42 +0,0 @@-{-# LANGUAGE TypeOperators, FlexibleInstances, TypeSynonymInstances,- IncoherentInstances, UndecidableInstances, TemplateHaskell, GADTs #-}------------------------------------------------------------------------------------ |--- Module : Data.Comp.MultiParam.Show--- Copyright : (c) 2011 Patrick Bahr, Tom Hvitved--- License : BSD3--- Maintainer : Tom Hvitved <hvitved@diku.dk>--- Stability : experimental--- Portability : non-portable (GHC Extensions)------ This module defines showing of signatures, which lifts to showing of terms.-------------------------------------------------------------------------------------module Data.Comp.MultiParam.Show- (- ShowHD(..)- ) where--import Data.Comp.MultiParam.Term-import Data.Comp.MultiParam.HDifunctor-import Data.Comp.MultiParam.Ops-import Data.Comp.MultiParam.Derive-import Data.Comp.MultiParam.FreshM---- Lift ShowHD to sums-$(derive [liftSum] [''ShowHD])--{-| From an 'ShowHD' higher-order difunctor an 'ShowHD' instance of the- corresponding term type can be derived. -}-instance (HDifunctor f, ShowHD f) => ShowHD (Cxt h f) where- showHD (In t) = showHD $ hfmap (K . showHD) t- showHD (Hole h) = unK h- showHD (Var p) = return $ show p--{-| Printing of terms. -}-instance (HDifunctor f, ShowHD f) => Show (Term f i) where- show = evalFreshM . showHD . toCxt . unTerm--instance (ShowHD f, Show p) => ShowHD (f :&: p) where- showHD (x :&: p) = do sx <- showHD x- return $ sx ++ " :&: " ++ show p
− src/Data/Comp/MultiParam/Sum.hs
@@ -1,180 +0,0 @@-{-# LANGUAGE TypeOperators, MultiParamTypeClasses, IncoherentInstances,- FlexibleInstances, FlexibleContexts, GADTs, TypeSynonymInstances,- ScopedTypeVariables, TemplateHaskell #-}------------------------------------------------------------------------------------ |--- Module : Data.Comp.MultiParam.Sum--- Copyright : (c) 2011 Patrick Bahr, Tom Hvitved--- License : BSD3--- Maintainer : Tom Hvitved <hvitved@diku.dk>--- Stability : experimental--- Portability : non-portable (GHC Extensions)------ This module provides the infrastructure to extend signatures.--------------------------------------------------------------------------------------module Data.Comp.MultiParam.Sum- (- (:<:),- (:+:),- caseHD,-- -- * Projections for Signatures and Terms- proj,- proj2,- proj3,- proj4,- proj5,- proj6,- proj7,- proj8,- proj9,- proj10,- project,- project2,- project3,- project4,- project5,- project6,- project7,- project8,- project9,- project10,- deepProject,- deepProject2,- deepProject3,- deepProject4,- deepProject5,- deepProject6,- deepProject7,- deepProject8,- deepProject9,- deepProject10,-- -- * Injections for Signatures and Terms- inj,- inj2,- inj3,- inj4,- inj5,- inj6,- inj7,- inj8,- inj9,- inj10,- inject,- inject2,- inject3,- inject4,- inject5,- inject6,- inject7,- inject8,- inject9,- inject10,- deepInject,- deepInject2,- deepInject3,- deepInject4,- deepInject5,- deepInject6,- deepInject7,- deepInject8,- deepInject9,- deepInject10,-- injectCxt,- liftCxt- ) where--import Prelude hiding (sequence)-import Control.Monad hiding (sequence)-import Data.Comp.MultiParam.Term-import Data.Comp.MultiParam.Algebra-import Data.Comp.MultiParam.Ops-import Data.Comp.MultiParam.Derive.Projections-import Data.Comp.MultiParam.Derive.Injections-import Data.Comp.MultiParam.HDifunctor-import Data.Comp.MultiParam.HDitraversable--$(liftM concat $ mapM projn [2..10])---- |Project the outermost layer of a term to a sub signature. If the signature--- @g@ is compound of /n/ atomic signatures, use @project@/n/ instead.-project :: (g :<: f) => NatM Maybe (Cxt h f a b) (g a (Cxt h f a b))-project (In t) = proj t-project (Hole _) = Nothing-project (Var _) = Nothing--$(liftM concat $ mapM projectn [2..10])---- | Tries to coerce a term/context to a term/context over a sub-signature. If--- the signature @g@ is compound of /n/ atomic signatures, use--- @deepProject@/n/ instead.-deepProject :: (HDitraversable g, g :<: f) => Term f i -> Maybe (Term g i)-{-# INLINE deepProject #-}-deepProject = appTSigFunM' proj--$(liftM concat $ mapM deepProjectn [2..10])-{-# INLINE deepProject2 #-}-{-# INLINE deepProject3 #-}-{-# INLINE deepProject4 #-}-{-# INLINE deepProject5 #-}-{-# INLINE deepProject6 #-}-{-# INLINE deepProject7 #-}-{-# INLINE deepProject8 #-}-{-# INLINE deepProject9 #-}-{-# INLINE deepProject10 #-}--$(liftM concat $ mapM injn [2..10])---- |Inject a term where the outermost layer is a sub signature. If the signature--- @g@ is compound of /n/ atomic signatures, use @inject@/n/ instead.-inject :: (g :<: f) => g a (Cxt h f a b) :-> Cxt h f a b-inject = In . inj--$(liftM concat $ mapM injectn [2..10])---- |Inject a term over a sub signature to a term over larger signature. If the--- signature @g@ is compound of /n/ atomic signatures, use @deepInject@/n/--- instead.-deepInject :: (HDifunctor g, g :<: f) => CxtFun g f-{-# INLINE deepInject #-}-deepInject = appSigFun inj--$(liftM concat $ mapM deepInjectn [2..10])-{-# INLINE deepInject2 #-}-{-# INLINE deepInject3 #-}-{-# INLINE deepInject4 #-}-{-# INLINE deepInject5 #-}-{-# INLINE deepInject6 #-}-{-# INLINE deepInject7 #-}-{-# INLINE deepInject8 #-}-{-# INLINE deepInject9 #-}-{-# INLINE deepInject10 #-}--{-| This function injects a whole context into another context. -}-injectCxt :: (HDifunctor g, g :<: f) => Cxt h g a (Cxt h f a b) :-> Cxt h f a b-injectCxt (In t) = inject $ hfmap injectCxt t-injectCxt (Hole x) = x-injectCxt (Var p) = Var p--{-| This function lifts the given functor to a context. -}-liftCxt :: (HDifunctor f, g :<: f) => g a b :-> Cxt Hole f a b-liftCxt g = simpCxt $ inj g--instance (Show (f a b i), Show (g a b i)) => Show ((f :+: g) a b i) where- show (Inl v) = show v- show (Inr v) = show v--instance (Ord (f a b i), Ord (g a b i)) => Ord ((f :+: g) a b i) where- compare (Inl _) (Inr _) = LT- compare (Inr _) (Inl _) = GT- compare (Inl x) (Inl y) = compare x y- compare (Inr x) (Inr y) = compare x y--instance (Eq (f a b i), Eq (g a b i)) => Eq ((f :+: g) a b i) where- (Inl x) == (Inl y) = x == y- (Inr x) == (Inr y) = x == y - _ == _ = False
− src/Data/Comp/MultiParam/Term.hs
@@ -1,123 +0,0 @@-{-# LANGUAGE EmptyDataDecls, GADTs, KindSignatures, Rank2Types,- MultiParamTypeClasses, TypeOperators, ScopedTypeVariables #-}------------------------------------------------------------------------------------ |--- Module : Data.Comp.MultiParam.Term--- Copyright : (c) 2011 Patrick Bahr, Tom Hvitved--- License : BSD3--- Maintainer : Tom Hvitved <hvitved@diku.dk>--- Stability : experimental--- Portability : non-portable (GHC Extensions)------ This module defines the central notion of /generalised parametrised terms/--- and their generalisation to generalised parametrised contexts.--------------------------------------------------------------------------------------module Data.Comp.MultiParam.Term- (- Cxt(..),- Hole,- NoHole,- Term(..),- Trm,- Context,- simpCxt,- toCxt,- hfmapCxt,- hdimapMCxt,- ParamFunctor (..)- ) where--import Prelude hiding (mapM, sequence, foldl, foldl1, foldr, foldr1)-import Data.Comp.MultiParam.HDifunctor-import Data.Comp.MultiParam.HDitraversable-import Control.Monad -import Unsafe.Coerce-import Data.Maybe (fromJust)--{-| This data type represents contexts over a signature. Contexts are terms- containing zero or more holes, and zero or more parameters. The first- parameter is a phantom type indicating whether the context has holes. The- second paramater is the signature of the context, in the form of a- "Data.Comp.MultiParam.HDifunctor". The third parameter is the type of- parameters, the fourth parameter is the type of holes, and the fifth- parameter is the GADT type. -}-data Cxt :: * -> ((* -> *) -> (* -> *) -> * -> *) -> (* -> *) -> (* -> *) -> * -> * where- In :: f a (Cxt h f a b) i -> Cxt h f a b i- Hole :: b i -> Cxt Hole f a b i- Var :: a i -> Cxt h f a b i--{-| Phantom type used to define 'Context'. -}-data Hole--{-| Phantom type used to define 'Term'. -}-data NoHole--{-| A context may contain holes. -}-type Context = Cxt Hole--{-| \"Preterms\" |-}-type Trm f a = Cxt NoHole f a (K ())--{-| A term is a context with no holes, where all occurrences of the- contravariant parameter is fully parametric. -}-newtype Term f i = Term{unTerm :: forall a. Trm f a i}--{-| Convert a difunctorial value into a context. -}-simpCxt :: HDifunctor f => f a b :-> Cxt Hole f a b-{-# INLINE simpCxt #-}-simpCxt = In . hfmap Hole--toCxt :: HDifunctor f => Trm f a :-> Cxt h f a b-{-# INLINE toCxt #-}-toCxt = unsafeCoerce---- | This is an instance of 'hfmap' for 'Cxt'.-hfmapCxt :: forall h f a b b'. HDifunctor f- => (b :-> b') -> Cxt h f a b :-> Cxt h f a b'-hfmapCxt f = run- where run :: Cxt h f a b :-> Cxt h f a b'- run (In t) = In $ hfmap run t- run (Var a) = Var a- run (Hole b) = Hole $ f b---- | This is an instance of 'hdimapM' for 'Cxt'.-hdimapMCxt :: forall h f a b b' m . (HDitraversable f, Monad m)- => NatM m b b' -> NatM m (Cxt h f a b) (Cxt h f a b')-hdimapMCxt f = run- where run :: NatM m (Cxt h f a b) (Cxt h f a b')- run (In t) = liftM In $ hdimapM run t- run (Var a) = return $ Var a- run (Hole b) = liftM Hole (f b)- - - -{-| Monads for which embedded @Trm@ values, which are parametric at top level,- can be made into monadic @Term@ values, i.e. \"pushing the parametricity- inwards\". -}-class ParamFunctor m where- termM :: (forall a. m (Trm f a i)) -> m (Term f i)--coerceTermM :: ParamFunctor m => (forall a. m (Trm f a i)) -> m (Term f i)-{-# INLINE coerceTermM #-}-coerceTermM t = unsafeCoerce t--{-# RULES- "termM/coerce'" termM = coerceTermM- #-}--instance ParamFunctor Maybe where- termM Nothing = Nothing- termM x = Just (Term $ fromJust x)--instance ParamFunctor (Either a) where- termM (Left x) = Left x- termM x = Right (Term $ fromRight x)- where fromRight :: Either a b -> b- fromRight (Right x) = x- fromRight _ = error "fromRight: Left"--instance ParamFunctor [] where- termM [] = []- termM l = Term (head l) : termM (tail l)
− src/Data/Comp/Number.hs
@@ -1,45 +0,0 @@------------------------------------------------------------------------------------ |--- Module : Data.Comp.Number--- Copyright : (c) 2012 Patrick Bahr--- License : BSD3--- Maintainer : Patrick Bahr <paba@diku.dk>--- Stability : experimental--- Portability : non-portable (GHC Extensions)--- --- This module provides functionality to number the components of a--- functorial value with consecutive integers.--------------------------------------------------------------------------------------module Data.Comp.Number - ( Numbered (..)- , unNumbered- , number- , Traversable ()) where--import Data.Traversable--import Control.Monad.State hiding (mapM)-import Prelude hiding (mapM)----- | This type is used for numbering components of a functorial value.-newtype Numbered a = Numbered (Int, a)--unNumbered :: Numbered a -> a-unNumbered (Numbered (_, x)) = x--instance Eq (Numbered a) where- Numbered (i,_) == Numbered (j,_) = i == j--instance Ord (Numbered a) where- compare (Numbered (i,_)) (Numbered (j,_)) = i `compare` j---- | This function numbers the components of the given functorial--- value with consecutive integers starting at 0.-number :: Traversable f => f a -> f (Numbered a)-number x = fst $ runState (mapM run x) 0 where- run b = do n <- get- put (n+1)- return $ Numbered (n,b)
src/Data/Comp/Ops.hs view
@@ -1,6 +1,16 @@-{-# LANGUAGE TypeOperators, MultiParamTypeClasses, IncoherentInstances,- FlexibleInstances, FlexibleContexts, GADTs, TypeSynonymInstances,- ScopedTypeVariables, FunctionalDependencies, UndecidableInstances #-}+{-# LANGUAGE ConstraintKinds #-}+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE FunctionalDependencies #-}+{-# LANGUAGE GADTs #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE PolyKinds #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE TypeOperators #-}+{-# LANGUAGE TypeSynonymInstances #-}+{-# LANGUAGE UndecidableInstances #-} -------------------------------------------------------------------------------- -- |@@ -19,13 +29,16 @@ import Data.Foldable import Data.Traversable+import Data.Kind import Control.Applicative-import Control.Monad hiding (sequence, mapM)+import Control.Monad hiding (mapM, sequence)+import Data.Comp.SubsumeCommon -import Prelude hiding (foldl, mapM, sequence, foldl1, foldr1, foldr) +import Prelude hiding (foldl, foldl1, foldr, foldr1, mapM, sequence) + -- Sums infixr 6 :+:@@ -35,6 +48,12 @@ data (f :+: g) e = Inl (f e) | Inr (g e) +fromInl :: (f :+: g) e -> Maybe (f e)+fromInl = caseF Just (const Nothing)++fromInr :: (f :+: g) e -> Maybe (g e)+fromInr = caseF (const Nothing) Just+ {-| Utility function to case on a functor sum, without exposing the internal representation of sums. -} caseF :: (f a -> b) -> (g a -> b) -> (f :+: g) a -> b@@ -71,29 +90,70 @@ sequence (Inl e) = Inl `liftM` sequence e sequence (Inr e) = Inr `liftM` sequence e --- | Signature containment relation for automatic injections. The left-hand must--- be an atomic signature, where as the right-hand side must have a list-like--- structure. Examples include @f :<: f :+: g@ and @g :<: f :+: (g :+: h)@,--- non-examples include @f :+: g :<: f :+: (g :+: h)@ and--- @f :<: (f :+: g) :+: h@.-class sub :<: sup where- inj :: sub a -> sup a- proj :: sup a -> Maybe (sub a)+infixl 5 :<:+infixl 5 :=: -instance (:<:) f f where- inj = id- proj = Just+type family Elem (f :: Type -> Type) (g :: Type -> Type) :: Emb where+ Elem f f = Found Here+ Elem (f1 :+: f2) g = Sum' (Elem f1 g) (Elem f2 g)+ Elem f (g1 :+: g2) = Choose (Elem f g1) (Elem f g2)+ Elem f g = NotFound -instance (:<:) f (f :+: g) where- inj = Inl- proj (Inl x) = Just x- proj (Inr _) = Nothing+class Subsume (e :: Emb) (f :: Type -> Type) (g :: Type -> Type) where+ inj' :: Proxy e -> f a -> g a+ prj' :: Proxy e -> g a -> Maybe (f a) -instance (f :<: g) => (:<:) f (h :+: g) where- inj = Inr . inj- proj (Inr x) = proj x- proj (Inl _) = Nothing+instance Subsume (Found Here) f f where+ inj' _ = id + prj' _ = Just++instance Subsume (Found p) f g => Subsume (Found (Le p)) f (g :+: g') where+ inj' _ = Inl . inj' (P :: Proxy (Found p))++ prj' _ (Inl x) = prj' (P :: Proxy (Found p)) x+ prj' _ _ = Nothing++instance Subsume (Found p) f g => Subsume (Found (Ri p)) f (g' :+: g) where+ inj' _ = Inr . inj' (P :: Proxy (Found p))++ prj' _ (Inr x) = prj' (P :: Proxy (Found p)) x+ prj' _ _ = Nothing++instance (Subsume (Found p1) f1 g, Subsume (Found p2) f2 g)+ => Subsume (Found (Sum p1 p2)) (f1 :+: f2) g where+ inj' _ (Inl x) = inj' (P :: Proxy (Found p1)) x+ inj' _ (Inr x) = inj' (P :: Proxy (Found p2)) x++ prj' _ x = case prj' (P :: Proxy (Found p1)) x of+ Just y -> Just (Inl y)+ _ -> case prj' (P :: Proxy (Found p2)) x of+ Just y -> Just (Inr y)+ _ -> Nothing++++-- | A constraint @f :<: g@ expresses that the signature @f@ is+-- subsumed by @g@, i.e. @f@ can be used to construct elements in @g@.+type f :<: g = (Subsume (ComprEmb (Elem f g)) f g)++inj :: forall f g a . (f :<: g) => f a -> g a+inj = inj' (P :: Proxy (ComprEmb (Elem f g)))++proj :: forall f g a . (f :<: g) => g a -> Maybe (f a)+proj = prj' (P :: Proxy (ComprEmb (Elem f g)))++type f :=: g = (f :<: g, g :<: f)++++spl :: (f :=: f1 :+: f2) => (f1 a -> b) -> (f2 a -> b) -> f a -> b+spl f1 f2 x = case inj x of+ Inl y -> f1 y+ Inr y -> f2 y+++ -- Products infixr 8 :*:@@ -107,6 +167,21 @@ fsnd :: (f :*: g) a -> g a fsnd (_ :*: x) = x++instance (Functor f, Functor g) => Functor (f :*: g) where+ fmap h (f :*: g) = (fmap h f :*: fmap h g)+++instance (Foldable f, Foldable g) => Foldable (f :*: g) where+ foldr f e (x :*: y) = foldr f (foldr f e y) x+ foldl f e (x :*: y) = foldl f (foldl f e x) y+++instance (Traversable f, Traversable g) => Traversable (f :*: g) where+ traverse f (x :*: y) = liftA2 (:*:) (traverse f x) (traverse f y)+ sequenceA (x :*: y) = liftA2 (:*:)(sequenceA x) (sequenceA y)+ mapM f (x :*: y) = liftM2 (:*:) (mapM f x) (mapM f y)+ sequence (x :*: y) = liftM2 (:*:) (sequence x) (sequence y) -- Constant Products
src/Data/Comp/Ordering.hs view
@@ -1,4 +1,6 @@-{-# LANGUAGE TypeOperators, GADTs, TemplateHaskell #-}+{-# LANGUAGE GADTs #-}+{-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE TypeOperators #-} -------------------------------------------------------------------------------- -- | -- Module : Data.Comp.Ordering@@ -17,12 +19,11 @@ OrdF(..) ) where -import Data.Comp.Term-import Data.Comp.Sum-import Data.Comp.Ops-import Data.Comp.Equality () import Data.Comp.Derive import Data.Comp.Derive.Utils+import Data.Comp.Equality ()+import Data.Comp.Ops+import Data.Comp.Term {-| From an 'OrdF' functor an 'Ord' instance of the corresponding@@ -38,7 +39,7 @@ compareF Hole{} Term{} = GT -- instance (OrdF f, Ord p) => OrdF (f :*: p) where--- compareF (v1 :*: p1) (v2 :*: p2) = +-- compareF (v1 :*: p1) (v2 :*: p2) = -- case compareF v1 v2 of -- EQ -> compare p1 p2 -- res -> res
− src/Data/Comp/Param.hs
@@ -1,32 +0,0 @@------------------------------------------------------------------------------------ |--- Module : Data.Comp.Param--- Copyright : (c) 2011 Patrick Bahr, Tom Hvitved--- License : BSD3--- Maintainer : Patrick Bahr <paba@diku.dk>, Tom Hvitved <hvitved@diku.dk>--- Stability : experimental--- Portability : non-portable (GHC Extensions)------ This module defines the infrastructure necessary to use--- /Parametric Compositional Data Types/. Parametric Compositional Data Types --- is an extension of Compositional Data Types with parametric--- higher-order abstract syntax (PHOAS) for usage with binders. Examples of--- usage are bundled with the package in the library--- @examples\/Examples\/Param@.-------------------------------------------------------------------------------------module Data.Comp.Param (- module Data.Comp.Param.Term- , module Data.Comp.Param.Algebra- , module Data.Comp.Param.Difunctor- , module Data.Comp.Param.Sum- , module Data.Comp.Param.Annotation- , module Data.Comp.Param.Equality- ) where--import Data.Comp.Param.Term-import Data.Comp.Param.Algebra-import Data.Comp.Param.Difunctor-import Data.Comp.Param.Sum-import Data.Comp.Param.Annotation-import Data.Comp.Param.Equality
− src/Data/Comp/Param/Algebra.hs
@@ -1,964 +0,0 @@-{-# LANGUAGE GADTs, Rank2Types, ScopedTypeVariables, TypeOperators,- FlexibleContexts, CPP #-}------------------------------------------------------------------------------------ |--- Module : Data.Comp.Param.Algebra--- Copyright : (c) 2011 Patrick Bahr, Tom Hvitved--- License : BSD3--- Maintainer : Tom Hvitved <hvitved@diku.dk>--- Stability : experimental--- Portability : non-portable (GHC Extensions)------ This module defines the notion of algebras and catamorphisms, and their--- generalizations to e.g. monadic versions and other (co)recursion schemes.--------------------------------------------------------------------------------------module Data.Comp.Param.Algebra (- -- * Algebras & Catamorphisms- Alg,- free,- cata,- cata',- appCxt,- - -- * Monadic Algebras & Catamorphisms- AlgM,- algM,- freeM,- cataM,- cataM',-- -- * Term Homomorphisms- CxtFun,- SigFun,- Hom,- appHom,- appHom',- compHom,- appSigFun,- appSigFun',- compSigFun,- compHomSigFun,- compSigFunHom,- hom,- compAlg,- compAlgSigFun,-- -- * Monadic Term Homomorphisms- CxtFunM,- SigFunM,- HomM,- SigFunMD,- HomMD,- sigFunM,- appHomM,- appTHomM,- appHomM',- appTHomM',- homM,- homMD,- appSigFunM,- appTSigFunM,- appSigFunM',- appTSigFunM',- appSigFunMD,- appTSigFunMD,- compHomM,- compHomM',- compSigFunM,- compSigFunHomM,- compSigFunHomM',- compAlgSigFunM,- compAlgSigFunM',- compAlgM,- compAlgM',-- -- * Coalgebras & Anamorphisms- Coalg,- ana,- CoalgM,- anaM,-- -- * R-Algebras & Paramorphisms- RAlg,- para,- RAlgM,- paraM,-- -- * R-Coalgebras & Apomorphisms- RCoalg,- apo,- RCoalgM,- apoM,-- -- * CV-Algebras & Histomorphisms- CVAlg,- histo,- CVAlgM,- histoM,-- -- * CV-Coalgebras & Futumorphisms- CVCoalg,- futu,- CVCoalg',- futu',- CVCoalgM,- futuM- ) where--import Prelude hiding (sequence, mapM)-import Control.Monad hiding (sequence, mapM)-import Data.Comp.Param.Term-import Data.Comp.Param.Ops-import Data.Comp.Param.Difunctor-import Data.Comp.Param.Ditraversable--{-| This type represents an algebra over a difunctor @f@ and carrier @a@. -}-type Alg f a = f a a -> a---{-| Construct a catamorphism for contexts over @f@ with holes of type @b@, from- the given algebra. -}-free :: forall h f a b. Difunctor f- => Alg f a -> (b -> a) -> Cxt h f a b -> a-free f g = run- where run :: Cxt h f a b -> a- run (In t) = f (difmap run t)- run (Hole x) = g x- run (Var p) = p--{-| Construct a catamorphism from the given algebra. -}-cata :: forall f a. Difunctor f => Alg f a -> Term f -> a -{-# NOINLINE [1] cata #-}-cata f (Term t) = run t- where run :: Trm f a -> a- run (In t) = f (difmap run t)- run (Var x) = x--{-| A generalisation of 'cata' from terms over @f@ to contexts over @f@, where- the holes have the type of the algebra carrier. -}-cata' :: Difunctor f => Alg f a -> Cxt h f a a -> a-{-# INLINE cata' #-}-cata' f = free f id--{-| This function applies a whole context into another context. -}-appCxt :: Difunctor f => Context f a (Cxt h f a b) -> Cxt h f a b-appCxt (In t) = In (difmap appCxt t)-appCxt (Hole x) = x-appCxt (Var p) = Var p--{-| This type represents a monadic algebra. It is similar to 'Alg' but- the return type is monadic. -}-type AlgM m f a = f a a -> m a--{-| Convert a monadic algebra into an ordinary algebra with a monadic- carrier. -}-algM :: (Ditraversable f, Monad m) => AlgM m f a -> Alg f (m a)-algM f x = disequence (dimap return id x) >>= f--{-| Construct a monadic catamorphism for contexts over @f@ with holes of type- @b@, from the given monadic algebra. -}-freeM :: forall m h f a b. (Ditraversable f, Monad m)- => AlgM m f a -> (b -> m a) -> Cxt h f a b -> m a-freeM f g = run- where run :: Cxt h f a b -> m a- run (In t) = f =<< dimapM run t- run (Hole x) = g x- run (Var p) = return p--{-| Construct a monadic catamorphism from the given monadic algebra. -}-cataM :: forall m f a. (Ditraversable f, Monad m) => AlgM m f a -> Term f -> m a-{-# NOINLINE [1] cataM #-}-cataM algm (Term t) = run t- where run :: Trm f a -> m a- run (In t) = algm =<< dimapM run t- run (Var x) = return x--{-| A generalisation of 'cataM' from terms over @f@ to contexts over @f@, where- the holes have the type of the monadic algebra carrier. -}-cataM' :: forall m h f a. (Ditraversable f, Monad m)- => AlgM m f a -> Cxt h f a (m a) -> m a-{-# NOINLINE [1] cataM' #-}-cataM' f = freeM f id--{-| This type represents a context function. -}-type CxtFun f g = forall h a b. Cxt h f a b -> Cxt h g a b---{-| This type represents a signature function. -}-type SigFun f g = forall a b. f a b -> g a b--{-| This type represents a term homomorphism. -}-type Hom f g = SigFun f (Context g)--{-| Apply a term homomorphism recursively to a term/context. -}-appHom :: forall f g. (Difunctor f, Difunctor g) => Hom f g -> CxtFun f g-{-# NOINLINE [1] appHom #-}-appHom f = run where- run :: CxtFun f g- run (In t) = appCxt (f (difmap run t))- run (Hole x) = Hole x- run (Var p) = Var p--{-| Apply a term homomorphism recursively to a term/context. -}-appHom' :: forall f g. (Difunctor g) => Hom f g -> CxtFun f g-{-# NOINLINE [1] appHom' #-}-appHom' f = run where- run :: CxtFun f g- run (In t) = appCxt (fmapCxt run (f t))- run (Hole x) = Hole x- run (Var p) = Var p--fmapCxt :: Difunctor f => (b -> b') -> Cxt h f a b -> Cxt h f a b'-fmapCxt f = run- where run (In t) = In $ difmap run t- run (Var a) = Var a- run (Hole b) = Hole $ f b--{-| Compose two term homomorphisms. -}-compHom :: (Difunctor g, Difunctor h)- => Hom g h -> Hom f g -> Hom f h-compHom f g = appHom f . g---{-| Compose an algebra with a term homomorphism to get a new algebra. -}-compAlg :: (Difunctor f, Difunctor g) => Alg g a -> Hom f g -> Alg f a-compAlg alg talg = cata' alg . talg--compAlgSigFun :: Alg g a -> SigFun f g -> Alg f a-compAlgSigFun alg sig = alg . sig---{-| This function applies a signature function to the given context. -}-appSigFun :: forall f g. (Difunctor f) => SigFun f g -> CxtFun f g-{-# NOINLINE [1] appSigFun #-}-appSigFun f = run- where run (In t) = In $ f $ difmap run t- run (Var x) = Var x- run (Hole x) = Hole x--- implementation via term homomorphisms--- appSigFun f = appHom $ hom f----- | This function applies a signature function to the given--- context. This is a top-bottom variant of 'appSigFun'.-appSigFun' :: forall f g. (Difunctor g) => SigFun f g -> CxtFun f g-{-# NOINLINE [1] appSigFun' #-}-appSigFun' f = run- where run (In t) = In $ difmap run $ f t- run (Var x) = Var x- run (Hole x) = Hole x--{-| This function composes two signature functions. -}-compSigFun :: SigFun g h -> SigFun f g -> SigFun f h-compSigFun f g = f . g--{-| This function composes a term homomorphism and a signature function. -}-compHomSigFun :: Hom g h -> SigFun f g -> Hom f h-compHomSigFun f g = f . g--{-| This function composes a term homomorphism and a signature function. -}-compSigFunHom :: (Difunctor g) => SigFun g h -> Hom f g -> Hom f h-compSigFunHom f g = appSigFun f . g---{-| Lifts the given signature function to the canonical term homomorphism. -}-hom :: Difunctor g => SigFun f g -> Hom f g-hom f = simpCxt . f--{-| This type represents a monadic signature function. -}-type SigFunM m f g = forall a b. f a b -> m (g a b)--{-| This type represents a monadic context function. -}-type CxtFunM m f g = forall h . SigFunM m (Cxt h f) (Cxt h g)--{-| This type represents a monadic signature function. It is similar to- 'SigFunM' but has monadic values also in the domain. -}-type SigFunMD m f g = forall a b. f a (m b) -> m (g a b)--{-| This type represents a monadic term homomorphism. -}-type HomM m f g = SigFunM m f (Context g)--{-| This type represents a monadic term homomorphism. It is similar to- 'HomM' but has monadic values also in the domain. -}-type HomMD m f g = SigFunMD m f (Context g)--{-| Lift the given signature function to a monadic signature function. Note that- term homomorphisms are instances of signature functions. Hence this function- also applies to term homomorphisms. -}-sigFunM :: Monad m => SigFun f g -> SigFunM m f g-sigFunM f = return . f--{-| Lift the given signature function to a monadic term homomorphism. -}-homM :: (Difunctor g, Monad m) => SigFunM m f g -> HomM m f g-homM f = liftM simpCxt . f---- | Apply a monadic term homomorphism recursively to a--- term/context. The monad is sequenced bottom-up.-appHomM :: forall f g m. (Ditraversable f, Difunctor g, Monad m)- => HomM m f g -> CxtFunM m f g-{-# NOINLINE [1] appHomM #-}-appHomM f = run- where run :: CxtFunM m f g- run (In t) = liftM appCxt . f =<< dimapM run t- run (Hole x) = return (Hole x)- run (Var p) = return (Var p)--{-| A restricted form of |appHomM| which only works for terms. -}-appTHomM :: (Ditraversable f, ParamFunctor m, Monad m, Difunctor g)- => HomM m f g -> Term f -> m (Term g)-appTHomM f (Term t) = termM (appHomM f t)----- | Apply a monadic term homomorphism recursively to a--- term/context. The monad is sequence top-down.-appHomM' :: forall f g m. (Ditraversable g, Monad m)- => HomM m f g -> CxtFunM m f g-appHomM' f = run- where run :: CxtFunM m f g- run (In t) = liftM appCxt . dimapMCxt run =<< f t- run (Var p) = return (Var p)- run (Hole x) = return (Hole x)--dimapMCxt :: (Ditraversable f, Monad m)- => (b -> m b') -> Cxt h f a b -> m (Cxt h f a b')-dimapMCxt f = run- where run (In t) = liftM In $ dimapM run t- run (Var a) = return $ Var a- run (Hole b) = liftM Hole (f b)--{-| A restricted form of |appHomM'| which only works for terms. -}-appTHomM' :: (Ditraversable g, ParamFunctor m, Monad m, Difunctor g)- => HomM m f g -> Term f -> m (Term g)-appTHomM' f (Term t) = termM (appHomM' f t)- --{-| This function constructs the unique monadic homomorphism from the- initial term algebra to the given term algebra. -}-homMD :: forall f g m. (Difunctor f, Difunctor g, Monad m)- => HomMD m f g -> CxtFunM m f g-homMD f = run - where run :: CxtFunM m f g- run (In t) = liftM appCxt (f (difmap run t))- run (Hole x) = return (Hole x)- run (Var p) = return (Var p)--{-| This function applies a monadic signature function to the given context. -}-appSigFunM :: forall m f g. (Ditraversable f, Monad m)- => SigFunM m f g -> CxtFunM m f g-appSigFunM f = run- where run :: CxtFunM m f g- run (In t) = liftM In . f =<< dimapM run t- run (Var x) = return $ Var x- run (Hole x) = return $ Hole x--- implementation via term homomorphisms--- appSigFunM f = appHomM $ hom' f--{-| A restricted form of |appSigFunM| which only works for terms. -}-appTSigFunM :: (Ditraversable f, ParamFunctor m, Monad m, Difunctor g)- => SigFunM m f g -> Term f -> m (Term g)-appTSigFunM f (Term t) = termM (appSigFunM f t)---- | This function applies a monadic signature function to the given--- context. This is a 'top-down variant of 'appSigFunM'.-appSigFunM' :: forall m f g. (Ditraversable g, Monad m)- => SigFunM m f g -> CxtFunM m f g-appSigFunM' f = run- where run :: CxtFunM m f g- run (In t) = liftM In . dimapM run =<< f t- run (Var x) = return $ Var x- run (Hole x) = return $ Hole x--{-| A restricted form of |appSigFunM'| which only works for terms. -}-appTSigFunM' :: (Ditraversable g, ParamFunctor m, Monad m, Difunctor g)- => SigFunM m f g -> Term f -> m (Term g)-appTSigFunM' f (Term t) = termM (appSigFunM' f t)--{-| This function applies a signature function to the given context. -}-appSigFunMD :: forall f g m. (Ditraversable f, Difunctor g, Monad m)- => SigFunMD m f g -> CxtFunM m f g-appSigFunMD f = run - where run :: CxtFunM m f g- run (In t) = liftM In (f (difmap run t))- run (Hole x) = return (Hole x)- run (Var p) = return (Var p)--{-| A restricted form of |appSigFunMD| which only works for terms. -}-appTSigFunMD :: (Ditraversable f, ParamFunctor m, Monad m, Difunctor g)- => SigFunMD m f g -> Term f -> m (Term g)-appTSigFunMD f (Term t) = termM (appSigFunMD f t)--{-| Compose two monadic term homomorphisms. -}-compHomM :: (Ditraversable g, Difunctor h, Monad m)- => HomM m g h -> HomM m f g -> HomM m f h-compHomM f g = appHomM f <=< g--{-| Compose two monadic term homomorphisms. -}-compHomM' :: (Ditraversable h, Monad m) => HomM m g h -> HomM m f g -> HomM m f h-compHomM' f g = appHomM' f <=< g--{-{-| Compose two monadic term homomorphisms. -}-compHomM_ :: (Difunctor h, Difunctor g, Monad m)- => Hom g h -> HomM m f g -> HomM m f h-compHomM_ f g = liftM (appHom f) . g--{-| Compose two monadic term homomorphisms. -}-compHomSigFunM :: Monad m => HomM m g h -> SigFunM m f g -> HomM m f h-compHomSigFunM f g = f <=< g-}--{-| Compose two monadic term homomorphisms. -}-compSigFunHomM :: (Ditraversable g, Monad m)- => SigFunM m g h -> HomM m f g -> HomM m f h-compSigFunHomM f g = appSigFunM f <=< g--{-| Compose two monadic term homomorphisms. -}-compSigFunHomM' :: (Ditraversable h, Monad m)- => SigFunM m g h -> HomM m f g -> HomM m f h-compSigFunHomM' f g = appSigFunM' f <=< g--{-| Compose a monadic algebra with a monadic term homomorphism to get a new- monadic algebra. -}-compAlgM :: (Ditraversable g, Monad m) => AlgM m g a -> HomM m f g -> AlgM m f a-compAlgM alg talg = freeM alg return <=< talg---{-| Compose a monadic algebra with a term homomorphism to get a new monadic- algebra. -}-compAlgM' :: (Ditraversable g, Monad m) => AlgM m g a -> Hom f g -> AlgM m f a-compAlgM' alg talg = freeM alg return . talg--{-| Compose a monadic algebra with a monadic signature function to get a new- monadic algebra. -}-compAlgSigFunM :: Monad m => AlgM m g a -> SigFunM m f g -> AlgM m f a-compAlgSigFunM alg talg = alg <=< talg---{-| Compose a monadic algebra with a signature function to get a new monadic- algebra. -}-compAlgSigFunM' :: AlgM m g a -> SigFun f g -> AlgM m f a-compAlgSigFunM' alg talg = alg . talg--{-| This function composes two monadic signature functions. -}-compSigFunM :: Monad m => SigFunM m g h -> SigFunM m f g -> SigFunM m f h-compSigFunM f g = f <=< g---------------------- Coalgebras ---------------------{-| This type represents a coalgebra over a difunctor @f@ and carrier @a@. The- list of @(a,b)@s represent the parameters that may occur in the constructed- value. The first component represents the seed of the parameter,- and the second component is the (polymorphic) parameter itself. If @f@ is- itself a binder, then the parameters bound by @f@ can be passed to the- covariant argument, thereby making them available to sub terms. -}-type Coalg f a = forall b. a -> [(a,b)] -> Either b (f b (a,[(a,b)]))--{-| Construct an anamorphism from the given coalgebra. -}-ana :: Difunctor f => Coalg f a -> a -> Term f-ana f x = Term $ anaAux f x- where anaAux :: Difunctor f => Coalg f a -> a -> (forall a. Trm f a)- anaAux f x = run (x,[])- where run (a,bs) = case f a bs of- Left p -> Var p- Right t -> In $ difmap run t--{-| This type represents a monadic coalgebra over a difunctor @f@ and carrier- @a@. -}-type CoalgM m f a = forall b. a -> [(a,b)] -> m (Either b (f b (a,[(a,b)])))--{-| Construct a monadic anamorphism from the given monadic coalgebra. -}-anaM :: forall a m f. (Ditraversable f, Monad m)- => CoalgM m f a -> a -> forall a. m (Trm f a)-anaM f x = run (x,[])- where run (a,bs) = do c <- f a bs- case c of- Left p -> return $ Var p- Right t -> liftM In $ dimapM run t-------------------------------------- R-Algebras & Paramorphisms -------------------------------------{-| This type represents an r-algebra over a difunctor @f@ and carrier @a@. -}-type RAlg f a = f a (Trm f a, a) -> a--{-| Construct a paramorphism from the given r-algebra. -}-para :: forall f a. Difunctor f => RAlg f a -> Term f -> a-para f (Term t) = run t- where run :: Trm f a -> a- run (In t) = f $ difmap (\x -> (x, run x)) t- run (Var x) = x--{-| This type represents a monadic r-algebra over a difunctor @f@ and carrier- @a@. -}-type RAlgM m f a = f a (Trm f a, a) -> m a-{-| Construct a monadic paramorphism from the given monadic r-algebra. -}-paraM :: forall m f a. (Ditraversable f, Monad m) => RAlgM m f a -> Term f -> m a-paraM f (Term t) = run t- where run :: Trm f a -> m a- run (In t) = f =<< dimapM (\x -> run x >>= \y -> return (x, y)) t- run (Var x) = return x-------------------------------------- R-Coalgebras & Apomorphisms -------------------------------------{-| This type represents an r-coalgebra over a difunctor @f@ and carrier @a@. -}-type RCoalg f a = forall b. a -> [(a,b)] -> Either b (f b (Either (Trm f b) (a,[(a,b)])))--{-| Construct an apomorphism from the given r-coalgebra. -}-apo :: Difunctor f => RCoalg f a -> a -> Term f-apo f x = Term (apoAux f x)- where apoAux :: Difunctor f => RCoalg f a -> a -> (forall a. Trm f a)- apoAux coa x = run (x,[])- where -- run :: (a,[(a,b)]) -> Trm f b- run (a,bs) = case coa a bs of- Left x -> Var x- Right t -> In $ difmap run' t- -- run' :: Either (Trm f b) (a,[(a,b)]) -> Trm f b- run' (Left t) = t- run' (Right x) = run x----{-| This type represents a monadic r-coalgebra over a functor @f@ and carrier- @a@. -}-type RCoalgM m f a = forall b. a -> [(a,b)] -> m (Either b (f b (Either (Trm f b) (a,[(a,b)]))))--{-| Construct a monadic apomorphism from the given monadic r-coalgebra. -}-apoM :: forall f m a. (Ditraversable f, Monad m)- => RCoalgM m f a -> a -> forall a. m (Trm f a)-apoM coa x = run (x,[]) - where run (a,bs) = do- res <- coa a bs- case res of- Left x -> return $ Var x- Right t -> liftM In $ dimapM run' t- run' (Left t) = return t- run' (Right x) = run x---------------------------------------- CV-Algebras & Histomorphisms ---------------------------------------{-| This type represents a cv-algebra over a difunctor @f@ and carrier @a@. -}-type CVAlg f a f' = f a (Trm f' a) -> a---- | This function applies 'projectA' at the tip of the term.-projectTip :: DistAnn f a f' => Trm f' a -> a-projectTip (In v) = snd $ projectA v-projectTip (Var p) = p--{-| Construct a histomorphism from the given cv-algebra. -}-histo :: forall f f' a. (Difunctor f, DistAnn f a f')- => CVAlg f a f' -> Term f -> a-histo alg = projectTip . cata run- where run :: Alg f (Trm f' a)- run v = In $ injectA (alg v') v'- where v' = dimap Var id v--{-| This type represents a monadic cv-algebra over a functor @f@ and carrier- @a@. -}-type CVAlgM m f a f' = f a (Trm f' a) -> m a--{-| Construct a monadic histomorphism from the given monadic cv-algebra. -}-histoM :: forall f f' m a. (Ditraversable f, Monad m, DistAnn f a f')- => CVAlgM m f a f' -> Term f -> m a-histoM alg (Term t) = liftM projectTip (run t)- where run :: Trm f a -> m (Trm f' a)- run (In t) = do t' <- dimapM run t- r <- alg t'- return $ In $ injectA r t'- run (Var p) = return $ Var p----------------------------------------- CV-Coalgebras & Futumorphisms ----------------------------------------{-| This type represents a cv-coalgebra over a difunctor @f@ and carrier @a@.- The list of @(a,b)@s represent the parameters that may occur in the- constructed value. The first component represents the seed of the parameter,- and the second component is the (polymorphic) parameter itself. If @f@ is- itself a binder, then the parameters bound by @f@ can be passed to the- covariant argument, thereby making them available to sub terms. -}-type CVCoalg f a = forall b. a -> [(a,b)]- -> Either b (f b (Context f b (a,[(a,b)])))--{-| Construct a futumorphism from the given cv-coalgebra. -}-futu :: Difunctor f => CVCoalg f a -> a -> Term f-futu f x = Term (futuAux f x)- where futuAux :: Difunctor f => CVCoalg f a -> a -> (forall a. Trm f a)- futuAux coa x = run (x,[])- where run (a,bs) = case coa a bs of- Left p -> Var p- Right t -> In $ difmap run' t- run' (In t) = In $ difmap run' t- run' (Hole x) = run x- run' (Var p) = Var p--{-| This type represents a monadic cv-coalgebra over a difunctor @f@ and carrier- @a@. -}-type CVCoalgM m f a = forall b. a -> [(a,b)]- -> m (Either b (f b (Context f b (a,[(a,b)]))))--{-| Construct a monadic futumorphism from the given monadic cv-coalgebra. -}-futuM :: forall f a m. (Ditraversable f, Monad m) =>- CVCoalgM m f a -> a -> forall a. m (Trm f a)-futuM coa x = run (x,[])- where run (a,bs) = do c <- coa a bs- case c of - Left p -> return $ Var p- Right t -> liftM In $ dimapM run' t- run' (In t) = liftM In $ dimapM run' t- run' (Hole x) = run x- run' (Var p) = return $ Var p--{-| This type represents a generalised cv-coalgebra over a difunctor @f@ and- carrier @a@. -}-type CVCoalg' f a = forall b. a -> [(a,b)] -> Context f b (a,[(a,b)])--{-| Construct a futumorphism from the given generalised cv-coalgebra. -}-futu' :: Difunctor f => CVCoalg' f a -> a -> Term f-futu' f x = Term (futuAux' f x)- where futuAux' :: Difunctor f => CVCoalg' f a -> a -> (forall a. Trm f a)- futuAux' coa x = run (x,[])- where run (a,bs) = run' $ coa a bs- run' (In t) = In $ difmap run' t- run' (Hole x) = run x- run' (Var p) = Var p--{----------------------------------------------- functions only used for rewrite rules ------------------------------------------------appAlgHom :: forall f g d. Difunctor g => Alg g d -> Hom f g -> Term f -> d-{-# NOINLINE [1] appAlgHom #-}-appAlgHom alg hom (Term t) = run t where- run :: Trm f d -> d- run (In t) = run' $ hom t- run (Var a) = a- run' :: Context g d (Trm f d) -> d- run' (In t) = alg $ fmap run' t- run' (Var a) = a- run' (Hole x) = run x----- | This function applies a signature function after a term homomorphism.-appSigFunHom :: forall f g h. (Difunctor g)- => SigFun g h -> Hom f g -> CxtFun f h-{-# NOINLINE [1] appSigFunHom #-}-appSigFunHom f g = run where- run :: CxtFun f h- run (In t) = run' $ g t- run (Var a) = Var a- run (Hole h) = Hole h- run' :: Context g a (Cxt h' f a b) -> Cxt h' h a b- run' (In t) = In $ f $ fmap run' t- run' (Var a) = Var a- run' (Hole h) = run h--appAlgHomM :: forall m g f d. Ditraversable g- => AlgM m g d -> HomM m f g -> Term f -> m d-appAlgHomM alg hom (Term t) = run t where- run :: Trm f d -> m d- run (In t) = run' =<< hom t- run (Var a) = return a- run' :: Context g d (Trm f d) -> m d- run' (In t) = alg =<< dimapM run' t- run' (Var a) = return a- run' (Hole x) = run x--appHomHomM :: forall m f g h. (Ditraversable g, Difunctor h)- => HomM m g h -> HomM m f g -> CxtFunM m f h-appHomHomM f g = run where--- run :: CxtFunM m f h- run (In t) = run' =<< g t- run (Var a) = return $ Var a- run (Hole h) = return $ Hole h--- run' :: Context g Any (Cxt h' f Any b) -> m (Cxt h' h Any b)- run' (In t) = liftM appCxt $ f =<< dimapM run' t- run' (Var a) = return $ Var a- run' (Hole h) = run h--appSigFunHomM :: forall m f g h. Ditraversable g- => SigFunM m g h -> HomM m f g -> CxtFunM m f h-appSigFunHomM f g = run where--- run :: CxtFunM m f h- run (In t) = run' =<< g t- run (Var a) = return $ Var a- run (Hole h) = return $ Hole h--- run' :: Context g Any (Cxt h' f Any b) -> m (Cxt h' h Any b)- run' (In t) = liftM In $ f =<< dimapM run' t- run' (Var a) = return $ Var a- run' (Hole h) = run h------------------------- rewrite rules ------------------------#ifndef NO_RULES-{-# RULES- "cata/appHom" forall (a :: Alg g d) (h :: Hom f g) x.- cata a (appHom h x) = cata (compAlg a h) x;-- "cata/appHom'" forall (a :: Alg g d) (h :: Hom f g) x.- cata a (appHom' h x) = appAlgHom a h x;-- "cata/appSigFun" forall (a :: Alg g d) (h :: SigFun f g) x.- cata a (appSigFun h x) = cata (compAlgSigFun a h) x;-- "cata/appSigFun'" forall (a :: Alg g d) (h :: SigFun f g) x.- cata a (appSigFun' h x) = appAlgHom a (hom h) x;-- "cata/appSigFunHom" forall (f :: Alg f3 d) (g :: SigFun f2 f3)- (h :: Hom f1 f2) x.- cata f (appSigFunHom g h x) = appAlgHom (compAlgSigFun f g) h x;-- "appAlgHom/appHom" forall (a :: Alg h d) (f :: Hom f g) (h :: Hom g h) x.- appAlgHom a h (appHom f x) = cata (compAlg a (compHom h f)) x;-- "appAlgHom/appHom'" forall (a :: Alg h d) (f :: Hom f g) (h :: Hom g h) x.- appAlgHom a h (appHom' f x) = appAlgHom a (compHom h f) x;-- "appAlgHom/appSigFun" forall (a :: Alg h d) (f :: SigFun f g) (h :: Hom g h) x.- appAlgHom a h (appSigFun f x) = cata (compAlg a (compHomSigFun h f)) x;-- "appAlgHom/appSigFun'" forall (a :: Alg h d) (f :: SigFun f g) (h :: Hom g h) x.- appAlgHom a h (appSigFun' f x) = appAlgHom a (compHomSigFun h f) x;-- "appAlgHom/appSigFunHom" forall (a :: Alg i d) (f :: Hom f g) (g :: SigFun g h)- (h :: Hom h i) x.- appAlgHom a h (appSigFunHom g f x)- = appAlgHom a (compHom (compHomSigFun h g) f) x;-- "appHom/appHom" forall (a :: Hom g h) (h :: Hom f g) x.- appHom a (appHom h x) = appHom (compHom a h) x;-- "appHom'/appHom'" forall (a :: Hom g h) (h :: Hom f g) x.- appHom' a (appHom' h x) = appHom' (compHom a h) x;-- "appHom'/appHom" forall (a :: Hom g h) (h :: Hom f g) x.- appHom' a (appHom h x) = appHom (compHom a h) x;-- "appHom/appHom'" forall (a :: Hom g h) (h :: Hom f g) x.- appHom a (appHom' h x) = appHom' (compHom a h) x;- - "appSigFun/appSigFun" forall (f :: SigFun g h) (g :: SigFun f g) x.- appSigFun f (appSigFun g x) = appSigFun (compSigFun f g) x;-- "appSigFun'/appSigFun'" forall (f :: SigFun g h) (g :: SigFun f g) x.- appSigFun' f (appSigFun' g x) = appSigFun' (compSigFun f g) x;-- "appSigFun/appSigFun'" forall (f :: SigFun g h) (g :: SigFun f g) x.- appSigFun f (appSigFun' g x) = appSigFunHom f (hom g) x;-- "appSigFun'/appSigFun" forall (f :: SigFun g h) (g :: SigFun f g) x.- appSigFun' f (appSigFun g x) = appSigFun (compSigFun f g) x;-- "appHom/appSigFun" forall (f :: Hom g h) (g :: SigFun f g) x.- appHom f (appSigFun g x) = appHom (compHomSigFun f g) x;-- "appHom/appSigFun'" forall (f :: Hom g h) (g :: SigFun f g) x.- appHom f (appSigFun' g x) = appHom' (compHomSigFun f g) x;-- "appHom'/appSigFun'" forall (f :: Hom g h) (g :: SigFun f g) x.- appHom' f (appSigFun' g x) = appHom' (compHomSigFun f g) x;-- "appHom'/appSigFun" forall (f :: Hom g h) (g :: SigFun f g) x.- appHom' f (appSigFun g x) = appHom (compHomSigFun f g) x;- - "appSigFun/appHom" forall (f :: SigFun g h) (g :: Hom f g) x.- appSigFun f (appHom g x) = appSigFunHom f g x;-- "appSigFun'/appHom'" forall (f :: SigFun g h) (g :: Hom f g) x.- appSigFun' f (appHom' g x) = appHom' (compSigFunHom f g) x;-- "appSigFun/appHom'" forall (f :: SigFun g h) (g :: Hom f g) x.- appSigFun f (appHom' g x) = appSigFunHom f g x;-- "appSigFun'/appHom" forall (f :: SigFun g h) (g :: Hom f g) x.- appSigFun' f (appHom g x) = appHom (compSigFunHom f g) x;- - "appSigFunHom/appSigFun" forall (f :: SigFun f3 f4) (g :: Hom f2 f3)- (h :: SigFun f1 f2) x.- appSigFunHom f g (appSigFun h x)- = appSigFunHom f (compHomSigFun g h) x;-- "appSigFunHom/appSigFun'" forall (f :: SigFun f3 f4) (g :: Hom f2 f3)- (h :: SigFun f1 f2) x.- appSigFunHom f g (appSigFun' h x)- = appSigFunHom f (compHomSigFun g h) x;-- "appSigFunHom/appHom" forall (f :: SigFun f3 f4) (g :: Hom f2 f3)- (h :: Hom f1 f2) x.- appSigFunHom f g (appHom h x)- = appSigFunHom f (compHom g h) x;-- "appSigFunHom/appHom'" forall (f :: SigFun f3 f4) (g :: Hom f2 f3)- (h :: Hom f1 f2) x.- appSigFunHom f g (appHom' h x)- = appSigFunHom f (compHom g h) x;-- "appSigFun/appSigFunHom" forall (f :: SigFun f3 f4) (g :: SigFun f2 f3)- (h :: Hom f1 f2) x.- appSigFun f (appSigFunHom g h x) = appSigFunHom (compSigFun f g) h x;-- "appSigFun'/appSigFunHom" forall (f :: SigFun f3 f4) (g :: SigFun f2 f3)- (h :: Hom f1 f2) x.- appSigFun' f (appSigFunHom g h x) = appSigFunHom (compSigFun f g) h x;-- "appHom/appSigFunHom" forall (f :: Hom f3 f4) (g :: SigFun f2 f3)- (h :: Hom f1 f2) x.- appHom f (appSigFunHom g h x) = appHom' (compHom (compHomSigFun f g) h) x;-- "appHom'/appSigFunHom" forall (f :: Hom f3 f4) (g :: SigFun f2 f3)- (h :: Hom f1 f2) x.- appHom' f (appSigFunHom g h x) = appHom' (compHom (compHomSigFun f g) h) x;-- "appSigFunHom/appSigFunHom" forall (f1 :: SigFun f4 f5) (f2 :: Hom f3 f4)- (f3 :: SigFun f2 f3) (f4 :: Hom f1 f2) x.- appSigFunHom f1 f2 (appSigFunHom f3 f4 x)- = appSigFunHom f1 (compHom (compHomSigFun f2 f3) f4) x;- #-}--{-# RULES - "cataM/appHomM" forall (a :: AlgM Maybe g d) (h :: HomM Maybe f g) x.- appHomM h x >>= cataM a = appAlgHomM a h x;-- "cataM/appHomM'" forall (a :: AlgM Maybe g d) (h :: HomM Maybe f g) x.- appHomM' h x >>= cataM a = appAlgHomM a h x;-- "cataM/appSigFunM" forall (a :: AlgM Maybe g d) (h :: SigFunM Maybe f g) x.- appSigFunM h x >>= cataM a = appAlgHomM a (homM h) x;-- "cataM/appSigFunM'" forall (a :: AlgM Maybe g d) (h :: SigFunM Maybe f g) x.- appSigFunM' h x >>= cataM a = appAlgHomM a (homM h) x;-- "cataM/appHom" forall (a :: AlgM m g d) (h :: Hom f g) x.- cataM a (appHom h x) = appAlgHomM a (sigFunM h) x;-- "cataM/appHom'" forall (a :: AlgM m g d) (h :: Hom f g) x.- cataM a (appHom' h x) = appAlgHomM a (sigFunM h) x;-- "cataM/appSigFun" forall (a :: AlgM m g d) (h :: SigFun f g) x.- cataM a (appSigFun h x) = appAlgHomM a (sigFunM $ hom h) x;-- "cataM/appSigFun'" forall (a :: AlgM m g d) (h :: SigFun f g) x.- cataM a (appSigFun' h x) = appAlgHomM a (sigFunM $ hom h) x;-- "cataM/appSigFun" forall (a :: AlgM m g d) (h :: SigFun f g) x.- cataM a (appSigFun h x) = appAlgHomM a (sigFunM $ hom h) x;-- "cataM/appSigFunHom" forall (a :: AlgM m h d) (g :: SigFun g h) (f :: Hom f g) x.- cataM a (appSigFunHom g f x) = appAlgHomM a (sigFunM $ compSigFunHom g f) x;-- "appHomM/appHomM" forall (a :: HomM Maybe g h) (h :: HomM Maybe f g) x.- appHomM h x >>= appHomM a = appHomM (compHomM a h) x;-- "appHomM/appSigFunM" forall (a :: HomM Maybe g h) (h :: SigFunM Maybe f g) x.- appSigFunM h x >>= appHomM a = appHomM (compHomSigFunM a h) x;-- "appHomM/appHomM'" forall (a :: HomM Maybe g h) (h :: HomM Maybe f g) x.- appHomM' h x >>= appHomM a = appHomHomM a h x;-- "appHomM/appSigFunM'" forall (a :: HomM Maybe g h) (h :: SigFunM Maybe f g) x.- appSigFunM' h x >>= appHomM a = appHomHomM a (homM h) x;-- "appHomM'/appHomM" forall (a :: HomM Maybe g h) (h :: HomM Maybe f g) x.- appHomM h x >>= appHomM' a = appHomM' (compHomM' a h) x;-- "appHomM'/appSigFunM" forall (a :: HomM Maybe g h) (h :: SigFunM Maybe f g) x.- appSigFunM h x >>= appHomM' a = appHomM' (compHomSigFunM a h) x;-- "appHomM'/appHomM'" forall (a :: HomM Maybe g h) (h :: HomM Maybe f g) x.- appHomM' h x >>= appHomM' a = appHomM' (compHomM' a h) x;-- "appHomM'/appSigFunM'" forall (a :: HomM Maybe g h) (h :: SigFunM Maybe f g) x.- appSigFunM' h x >>= appHomM' a = appHomM' (compHomSigFunM a h) x;-- "appHomM/appHom" forall (a :: HomM m g h) (h :: Hom f g) x.- appHomM a (appHom h x) = appHomHomM a (sigFunM h) x;-- "appHomM/appSigFun" forall (a :: HomM m g h) (h :: SigFun f g) x.- appHomM a (appSigFun h x) = appHomHomM a (sigFunM $ hom h) x;-- "appHomM'/appHom" forall (a :: HomM m g h) (h :: Hom f g) x.- appHomM' a (appHom h x) = appHomM' (compHomM' a (sigFunM h)) x;-- "appHomM'/appSigFun" forall (a :: HomM m g h) (h :: SigFun f g) x.- appHomM' a (appSigFun h x) = appHomM' (compHomSigFunM a (sigFunM h)) x;-- "appHomM/appHom'" forall (a :: HomM m g h) (h :: Hom f g) x.- appHomM a (appHom' h x) = appHomHomM a (sigFunM h) x;-- "appHomM/appSigFun'" forall (a :: HomM m g h) (h :: SigFun f g) x.- appHomM a (appSigFun' h x) = appHomHomM a (sigFunM $ hom h) x;-- "appHomM'/appHom'" forall (a :: HomM m g h) (h :: Hom f g) x.- appHomM' a (appHom' h x) = appHomM' (compHomM' a (sigFunM h)) x;-- "appHomM'/appSigFun'" forall (a :: HomM m g h) (h :: SigFun f g) x.- appHomM' a (appSigFun' h x) = appHomM' (compHomSigFunM a (sigFunM h)) x;-- "appSigFunM/appHomM" forall (a :: SigFunM Maybe g h) (h :: HomM Maybe f g) x.- appHomM h x >>= appSigFunM a = appSigFunHomM a h x;-- "appSigFunHomM/appSigFunM" forall (a :: SigFunM Maybe g h) (h :: SigFunM Maybe f g) x.- appSigFunM h x >>= appSigFunM a = appSigFunM (compSigFunM a h) x;-- "appSigFunM/appHomM'" forall (a :: SigFunM Maybe g h) (h :: HomM Maybe f g) x.- appHomM' h x >>= appSigFunM a = appSigFunHomM a h x;-- "appSigFunM/appSigFunM'" forall (a :: SigFunM Maybe g h) (h :: SigFunM Maybe f g) x.- appSigFunM' h x >>= appSigFunM a = appSigFunHomM a (homM h) x;-- "appSigFunM'/appHomM" forall (a :: SigFunM Maybe g h) (h :: HomM Maybe f g) x.- appHomM h x >>= appSigFunM' a = appHomM' (compSigFunHomM' a h) x;-- "appSigFunM'/appSigFunM" forall (a :: SigFunM Maybe g h) (h :: SigFunM Maybe f g) x.- appSigFunM h x >>= appSigFunM' a = appSigFunM' (compSigFunM a h) x;-- "appSigFunM'/appHomM'" forall (a :: SigFunM Maybe g h) (h :: HomM Maybe f g) x.- appHomM' h x >>= appSigFunM' a = appHomM' (compSigFunHomM' a h) x;-- "appSigFunM'/appSigFunM'" forall (a :: SigFunM Maybe g h) (h :: SigFunM Maybe f g) x.- appSigFunM' h x >>= appSigFunM' a = appSigFunM' (compSigFunM a h) x;-- "appSigFunM/appHom" forall (a :: SigFunM m g h) (h :: Hom f g) x.- appSigFunM a (appHom h x) = appSigFunHomM a (sigFunM h) x;-- "appSigFunM/appSigFun" forall (a :: SigFunM m g h) (h :: SigFun f g) x.- appSigFunM a (appSigFun h x) = appSigFunHomM a (sigFunM $ hom h) x;-- "appSigFunM'/appHom" forall (a :: SigFunM m g h) (h :: Hom f g) x.- appSigFunM' a (appHom h x) = appHomM' (compSigFunHomM' a (sigFunM h)) x;-- "appSigFunM'/appSigFun" forall (a :: SigFunM m g h) (h :: SigFun f g) x.- appSigFunM' a (appSigFun h x) = appSigFunM' (compSigFunM a (sigFunM h)) x;-- "appSigFunM/appHom'" forall (a :: SigFunM m g h) (h :: Hom f g) x.- appSigFunM a (appHom' h x) = appSigFunHomM a (sigFunM h) x;-- "appSigFunM/appSigFun'" forall (a :: SigFunM m g h) (h :: SigFun f g) x.- appSigFunM a (appSigFun' h x) = appSigFunHomM a (sigFunM $ hom h) x;-- "appSigFunM'/appHom'" forall (a :: SigFunM m g h) (h :: Hom f g) x.- appSigFunM' a (appHom' h x) = appHomM' (compSigFunHomM' a (sigFunM h)) x;-- "appSigFunM'/appSigFun'" forall (a :: SigFunM m g h) (h :: SigFun f g) x.- appSigFunM' a (appSigFun' h x) = appSigFunM' (compSigFunM a (sigFunM h)) x;--- "appHom/appHomM" forall (a :: Hom g h) (h :: HomM m f g) x.- appHomM h x >>= (return . appHom a) = appHomM (compHomM_ a h) x;- #-}-#endif--}
− src/Data/Comp/Param/Annotation.hs
@@ -1,79 +0,0 @@-{-# LANGUAGE TypeOperators, MultiParamTypeClasses, FlexibleInstances,- UndecidableInstances, Rank2Types, GADTs, ScopedTypeVariables #-}------------------------------------------------------------------------------------ |--- Module : Data.Comp.Param.Annotation--- Copyright : (c) 2010-2011 Patrick Bahr, Tom Hvitved--- License : BSD3--- Maintainer : Tom Hvitved <hvitved@diku.dk>--- Stability : experimental--- Portability : non-portable (GHC Extensions)------ This module defines annotations on signatures.--------------------------------------------------------------------------------------module Data.Comp.Param.Annotation- (- (:&:) (..),- (:*:) (..),- DistAnn (..),- RemA (..),- liftA,- liftA',- stripA,- propAnn,- propAnnM,- ann,- project'- ) where--import Data.Comp.Param.Difunctor-import Data.Comp.Param.Term-import Data.Comp.Param.Sum-import Data.Comp.Param.Ops-import Data.Comp.Param.Algebra--import Control.Monad--{-| Transform a function with a domain constructed from a functor to a function- with a domain constructed with the same functor, but with an additional- annotation. -}-liftA :: (RemA s s') => (s' a b -> t) -> s a b -> t-liftA f v = f (remA v)--{-| Transform a function with a domain constructed from a functor to a function- with a domain constructed with the same functor, but with an additional- annotation. -}-liftA' :: (DistAnn s' p s, Difunctor s')- => (s' a b -> Cxt h s' c d) -> s a b -> Cxt h s c d-liftA' f v = let (v',p) = projectA v- in ann p (f v')--{-| Strip the annotations from a term over a functor with annotations. -}-stripA :: (RemA g f, Difunctor g) => CxtFun g f-stripA = appSigFun remA--{-| Lift a term homomorphism over signatures @f@ and @g@ to a term homomorphism- over the same signatures, but extended with annotations. -}-propAnn :: (DistAnn f p f', DistAnn g p g', Difunctor g) - => Hom f g -> Hom f' g'-propAnn hom f' = ann p (hom f)- where (f,p) = projectA f'--{-| Lift a monadic term homomorphism over signatures @f@ and @g@ to a monadic- term homomorphism over the same signatures, but extended with annotations. -}-propAnnM :: (DistAnn f p f', DistAnn g p g', Difunctor g, Monad m) - => HomM m f g -> HomM m f' g'-propAnnM hom f' = liftM (ann p) (hom f)- where (f,p) = projectA f'--{-| Annotate each node of a term with a constant value. -}-ann :: (DistAnn f p g, Difunctor f) => p -> CxtFun f g-ann c = appSigFun (injectA c)--{-| This function is similar to 'project' but applies to signatures-with an annotation which is then ignored. -}-project' :: forall s s' f h a b . (RemA s s', s :<: f) => - Cxt h f a b -> Maybe (s' a (Cxt h f a b))-project' v = liftM remA (project v :: Maybe (s a (Cxt h f a b)))
− src/Data/Comp/Param/Derive.hs
@@ -1,57 +0,0 @@-{-# LANGUAGE TemplateHaskell #-}------------------------------------------------------------------------------------ |--- Module : Data.Comp.Param.Derive--- Copyright : (c) 2011 Patrick Bahr, Tom Hvitved--- License : BSD3--- Maintainer : Tom Hvitved <hvitved@diku.dk>--- Stability : experimental--- Portability : non-portable (GHC Extensions)------ This module contains functionality for automatically deriving boilerplate--- code using Template Haskell. Examples include instances of 'Difunctor',--- 'Difoldable', and 'Ditraversable'.--------------------------------------------------------------------------------------module Data.Comp.Param.Derive- (- derive,- -- |Derive boilerplate instances for parametric signatures, i.e.- -- signatures for parametric compositional data types.-- -- ** EqD- module Data.Comp.Param.Derive.Equality,- -- ** OrdD- module Data.Comp.Param.Derive.Ordering,- -- ** ShowD- module Data.Comp.Param.Derive.Show,- -- ** Difunctor- module Data.Comp.Param.Derive.Difunctor,- -- ** Ditraversable- module Data.Comp.Param.Derive.Ditraversable,- -- ** Smart Constructors- module Data.Comp.Param.Derive.SmartConstructors,- -- ** Smart Constructors w/ Annotations- module Data.Comp.Param.Derive.SmartAConstructors,- -- ** Lifting to Sums- liftSum- ) where--import Data.Comp.Derive.Utils (derive, liftSumGen)-import Data.Comp.Param.Derive.Equality-import Data.Comp.Param.Derive.Ordering-import Data.Comp.Param.Derive.Show-import Data.Comp.Param.Derive.Difunctor-import Data.Comp.Param.Derive.Ditraversable-import Data.Comp.Param.Derive.SmartConstructors-import Data.Comp.Param.Derive.SmartAConstructors-import Data.Comp.Param.Ops ((:+:), caseD)--import Language.Haskell.TH--{-| Given the name of a type class, where the first parameter is a difunctor,- lift it to sums of difunctors. Example: @class ShowD f where ...@ is lifted- as @instance (ShowD f, ShowD g) => ShowD (f :+: g) where ... @. -}-liftSum :: Name -> Q [Dec]-liftSum = liftSumGen 'caseD ''(:+:)
− src/Data/Comp/Param/Derive/Difunctor.hs
@@ -1,96 +0,0 @@-{-# LANGUAGE TemplateHaskell, ScopedTypeVariables #-}------------------------------------------------------------------------------------ |--- Module : Data.Comp.Param.Derive.Functor--- Copyright : (c) 2011 Patrick Bahr, Tom Hvitved--- License : BSD3--- Maintainer : Tom Hvitved <hvitved@diku.dk>--- Stability : experimental--- Portability : non-portable (GHC Extensions)------ Automatically derive instances of @Difunctor@.--------------------------------------------------------------------------------------module Data.Comp.Param.Derive.Difunctor- (- Difunctor,- makeDifunctor- ) where--import Data.Comp.Derive.Utils-import Data.Comp.Param.Difunctor-import Language.Haskell.TH--{-| Derive an instance of 'Difunctor' for a type constructor of any parametric- kind taking at least two arguments. -}-makeDifunctor :: Name -> Q [Dec]-makeDifunctor fname = do- -- Comments below apply to the example where name = T, args = [a,b,c], and- -- constrs = [(X,[c]), (Y,[a,c]), (Z,[b -> c])], i.e. the data type- -- declaration: T a b c = X c | Y a c | Z (b -> c)- TyConI (DataD _ name args constrs _) <- abstractNewtypeQ $ reify fname- -- coArg = c (covariant difunctor argument)- let coArg :: Name = tyVarBndrName $ last args- -- conArg = b (contravariant difunctor argument)- let conArg :: Name = tyVarBndrName $ last $ init args- -- argNames = [a]- let argNames = map (VarT . tyVarBndrName) (init $ init args)- -- compType = T a- let complType = foldl AppT (ConT name) argNames- -- classType = Difunctor (T a)- let classType = AppT (ConT ''Difunctor) complType- -- constrs' = [(X,[c]), (Y,[a,c]), (Z,[b -> c])]- constrs' :: [(Name,[Type])] <- mapM normalConExp constrs- dimapDecl <- funD 'dimap (map (dimapClause conArg coArg) constrs')- return [InstanceD [] classType [dimapDecl]]- where dimapClause :: Name -> Name -> (Name,[Type]) -> ClauseQ- dimapClause conArg coArg (constr, args) = do- fn <- newName "_f"- gn <- newName "_g"- varNs <- newNames (length args) "x"- let f = varE fn- let g = varE gn- let fp = VarP fn- let gp = VarP gn- -- Pattern for the constructor- let pat = ConP constr $ map VarP varNs- body <- dimapArgs conArg coArg f g (zip varNs args) (conE constr)- return $ Clause [fp, gp, pat] (NormalB body) []- dimapArgs :: Name -> Name -> ExpQ -> ExpQ- -> [(Name, Type)] -> ExpQ -> ExpQ- dimapArgs _ _ _ _ [] acc =- acc- dimapArgs conArg coArg f g ((x,tp):tps) acc =- dimapArgs conArg coArg f g tps- (acc `appE` (dimapArg conArg coArg tp f g `appE` varE x))- -- Given the name of the difunctor variables, a type, and the two- -- arguments to dimap, return the expression that should be applied- -- to the parameter of the given type.- -- Example: dimapArg a b (a -> b) f g yields the expression- -- [|\x -> g . x . f|]- dimapArg :: Name -> Name -> Type -> ExpQ -> ExpQ -> ExpQ- dimapArg conArg coArg tp f g- | not (containsType tp (VarT conArg)) &&- not (containsType tp (VarT coArg)) = [| id |]- | otherwise =- case tp of- VarT a | a == conArg -> f- | a == coArg -> g- AppT (AppT ArrowT tp1) tp2 -> do- xn <- newName "x"- let ftp1 = dimapArg conArg coArg tp1 f g- let ftp2 = dimapArg conArg coArg tp2 f g- lamE [varP xn]- (infixE (Just ftp2)- [|(.)|]- (Just $ infixE (Just $ varE xn)- [|(.)|]- (Just ftp1)))- SigT tp' _ ->- dimapArg conArg coArg tp' f g- _ ->- if containsType tp (VarT conArg) then- [| dimap $f $g |]- else- [| fmap $g |]
− src/Data/Comp/Param/Derive/Ditraversable.hs
@@ -1,88 +0,0 @@-{-# LANGUAGE TemplateHaskell #-}------------------------------------------------------------------------------------ |--- Module : Data.Comp.Param.Derive.Ditraversable--- Copyright : (c) 2010-2011 Patrick Bahr--- License : BSD3--- Maintainer : Patrick Bahr <paba@diku.dk>--- Stability : experimental--- Portability : non-portable (GHC Extensions)------ Automatically derive instances of @Ditraversable@.--------------------------------------------------------------------------------------module Data.Comp.Param.Derive.Ditraversable- (- Ditraversable,- makeDitraversable- ) where--import Data.Comp.Derive.Utils-import Data.Comp.Param.Ditraversable-import Data.Traversable (mapM)-import Language.Haskell.TH-import Data.Maybe-import Control.Monad hiding (mapM)-import Prelude hiding (mapM)--iter 0 _ e = e-iter n f e = iter (n-1) f (f `appE` e)--iter' n f e = run n f e- where run 0 _ e = e- run m f e = let f' = iter (m-1) [|fmap|] f- in run (m-1) f (f' `appE` e)--{-| Derive an instance of 'Traversable' for a type constructor of any- first-order kind taking at least one argument. -}-makeDitraversable :: Name -> Q [Dec]-makeDitraversable fname = do- TyConI (DataD _cxt name args constrs _deriving) <- abstractNewtypeQ $ reify fname- let fArg = VarT . tyVarBndrName $ last args- aArg = VarT . tyVarBndrName $ last (init args)- funTy = foldl AppT ArrowT [aArg,fArg]- argNames = map (VarT . tyVarBndrName) (init $ init args)- complType = foldl AppT (ConT name) argNames- classType = foldl1 AppT [ConT ''Ditraversable, complType]- normConstrs <- mapM normalConExp constrs- constrs' <- mapM (mkPatAndVars . isFarg fArg funTy) normConstrs- mapMDecl <- funD 'dimapM (map mapMClause constrs')- sequenceDecl <- funD 'disequence (map sequenceClause constrs')- return [InstanceD [] classType [mapMDecl,sequenceDecl]]- where isFarg fArg funTy (constr, args) =- (constr, map (\t -> (t `containsType'` fArg, t `containsType'` funTy)) args)- checksAarg aArg (_,args) = any (`containsType` aArg) args- filterVar _ _ nonFarg ([],[]) x = nonFarg x- filterVar farg _ _ ([depth],[]) x = farg depth x- filterVar _ aarg _ ([_],[depth]) x = aarg depth x- filterVar _ _ _ _ _ = error "functor variable occurring twice in argument type"- filterVars args varNs farg aarg nonFarg = zipWith (filterVar farg aarg nonFarg) args varNs- mkCPat constr varNs = ConP constr $ map mkPat varNs- mkPat = VarP- mkPatAndVars (constr, args) =- do varNs <- newNames (length args) "x"- return (conE constr, mkCPat constr varNs,- any (not . null . fst) args || any (not . null . snd) args, map varE varNs,- catMaybes $ filterVars args varNs (\x y -> Just (False,x,y)) (\x y -> Just (True, x, y)) (const Nothing))-- -- Note: the monadic versions are not defined- -- applicatively, as this results in a considerable- -- performance penalty (by factor 2)!- mapMClause (con, pat,hasFargs,allVars, fvars) =- do fn <- newName "f"- let f = varE fn- fp = if hasFargs then VarP fn else WildP- conAp = foldl appE con allVars- addDi False _ x = x- addDi True d x = [|dimapM $(f)|]- conBind (fun,d,x) y = [| $(iter d [|mapM|] (addDi fun d f)) $(varE x) >>= $(lamE [varP x] y)|]- body <- foldr conBind [|return $conAp|] fvars- return $ Clause [fp, pat] (NormalB body) []- sequenceClause (con, pat,hasFargs,allVars, fvars) =- do let conAp = foldl appE con allVars- varE' False _ x = varE x- varE' True d x = appE (iter d [|fmap|] [|disequence|]) (varE x)- conBind (fun,d, x) y = [| $(iter' d [|sequence|] (varE' fun d x)) >>= $(lamE [varP x] y)|]- body <- foldr conBind [|return $conAp|] fvars- return $ Clause [pat] (NormalB body) []
− src/Data/Comp/Param/Derive/Equality.hs
@@ -1,84 +0,0 @@-{-# LANGUAGE TemplateHaskell, FlexibleInstances, IncoherentInstances,- ScopedTypeVariables #-}------------------------------------------------------------------------------------ |--- Module : Data.Comp.Param.Derive.Equality--- Copyright : (c) 2011 Patrick Bahr, Tom Hvitved--- License : BSD3--- Maintainer : Tom Hvitved <hvitved@diku.dk>--- Stability : experimental--- Portability : non-portable (GHC Extensions)------ Automatically derive instances of @EqD@.-------------------------------------------------------------------------------------module Data.Comp.Param.Derive.Equality- (- EqD(..),- makeEqD- ) where--import Data.Comp.Derive.Utils-import Data.Comp.Param.FreshM hiding (Name)-import Data.Comp.Param.Equality-import Control.Monad-import Language.Haskell.TH hiding (Cxt, match)--{-| Derive an instance of 'EqD' for a type constructor of any parametric- kind taking at least two arguments. -}-makeEqD :: Name -> Q [Dec]-makeEqD fname = do- -- Comments below apply to the example where name = T, args = [a,b,c], and- -- constrs = [(X,[c]), (Y,[a,c]), (Z,[b -> c])], i.e. the data type- -- declaration: T a b c = X c | Y a c | Z (b -> c)- TyConI (DataD _ name args constrs _) <- abstractNewtypeQ $ reify fname- -- coArg = c (covariant difunctor argument)- let coArg :: Name = tyVarBndrName $ last args- -- conArg = b (contravariant difunctor argument)- let conArg :: Name = tyVarBndrName $ last $ init args- -- argNames = [a]- let argNames = map (VarT . tyVarBndrName) (init $ init args)- -- compType = T a- let complType = foldl AppT (ConT name) argNames- -- classType = Difunctor (T a)- let classType = AppT (ConT ''EqD) complType- -- constrs' = [(X,[c]), (Y,[a,c]), (Z,[b -> c])]- constrs' :: [(Name,[Type])] <- mapM normalConExp constrs- let defC = if length constrs < 2 then- []- else- [clause [wildP,wildP] (normalB [|return False|]) []]- eqDDecl <- funD 'eqD (map (eqDClause conArg coArg) constrs' ++ defC)- let context = map (\arg -> ClassP ''Eq [arg]) argNames- return [InstanceD context classType [eqDDecl]]- where eqDClause :: Name -> Name -> (Name,[Type]) -> ClauseQ- eqDClause conArg coArg (constr, args) = do- varXs <- newNames (length args) "x"- varYs <- newNames (length args) "y"- -- Patterns for the constructors- let patx = ConP constr $ map VarP varXs- let paty = ConP constr $ map VarP varYs- body <- eqDBody conArg coArg (zip3 varXs varYs args)- return $ Clause [patx,paty] (NormalB body) []- eqDBody :: Name -> Name -> [(Name, Name, Type)] -> ExpQ- eqDBody conArg coArg x =- [|liftM and (sequence $(listE $ map (eqDB conArg coArg) x))|]- eqDB :: Name -> Name -> (Name, Name, Type) -> ExpQ- eqDB conArg coArg (x, y, tp)- | not (containsType tp (VarT conArg)) &&- not (containsType tp (VarT coArg)) =- [| return $ $(varE x) == $(varE y) |]- | otherwise =- case tp of- VarT a- | a == coArg -> [| peq $(varE x) $(varE y) |]- AppT (AppT ArrowT (VarT a)) _- | a == conArg ->- [| withName (\v -> peq ($(varE x) v) ($(varE y) v)) |]- SigT tp' _ ->- eqDB conArg coArg (x, y, tp')- _ ->- if containsType tp (VarT conArg) then- [| eqD $(varE x) $(varE y) |]- else- [| peq $(varE x) $(varE y) |]
− src/Data/Comp/Param/Derive/Injections.hs
@@ -1,86 +0,0 @@-{-# LANGUAGE TemplateHaskell #-}------------------------------------------------------------------------------------ |--- Module : Data.Comp.Param.Derive.Injections--- Copyright : (c) 2011 Patrick Bahr, Tom Hvitved--- License : BSD3--- Maintainer : Tom Hvitved <hvitved@diku.dk>--- Stability : experimental--- Portability : non-portable (GHC Extensions)------ Derive functions for signature injections.--------------------------------------------------------------------------------------module Data.Comp.Param.Derive.Injections- (- injn,- injectn,- deepInjectn- ) where--import Language.Haskell.TH hiding (Cxt)-import Data.Comp.Param.Difunctor-import Data.Comp.Param.Term-import Data.Comp.Param.Algebra (CxtFun, appSigFun)-import Data.Comp.Param.Ops ((:+:)(..), (:<:)(..))--injn :: Int -> Q [Dec]-injn n = do- let i = mkName $ "inj" ++ show n- let fvars = map (\n -> mkName $ 'f' : show n) [1..n]- let gvar = mkName "g"- let avar = mkName "a"- let bvar = mkName "b"- let xvar = mkName "x"- let d = [funD i [clause [varP xvar] (normalB $ genDecl xvar n) []]]- sequence $ sigD i (genSig fvars gvar avar bvar) : d- where genSig fvars gvar avar bvar = do- let cxt = map (\f -> classP ''(:<:) [varT f, varT gvar]) fvars- let tp = foldl1 (\a f -> conT ''(:+:) `appT` f `appT` a)- (map varT fvars)- let tp' = arrowT `appT` (tp `appT` varT avar `appT` varT bvar)- `appT` (varT gvar `appT` varT avar `appT`- varT bvar)- forallT (map PlainTV $ gvar : avar : bvar : fvars)- (sequence cxt) tp'- genDecl x n = [| case $(varE x) of- Inl x -> $(varE $ mkName "inj") x- Inr x -> $(varE $ mkName $ "inj" ++- if n > 2 then show (n - 1) else "") x |]-injectn :: Int -> Q [Dec]-injectn n = do- let i = mkName ("inject" ++ show n)- let fvars = map (\n -> mkName $ 'f' : show n) [1..n]- let gvar = mkName "g"- let avar = mkName "a"- let bvar = mkName "b"- let d = [funD i [clause [] (normalB $ genDecl n) []]]- sequence $ sigD i (genSig fvars gvar avar bvar) : d- where genSig fvars gvar avar bvar = do- let hvar = mkName "h"- let cxt = map (\f -> classP ''(:<:) [varT f, varT gvar]) fvars- let tp = foldl1 (\a f -> conT ''(:+:) `appT` f `appT` a)- (map varT fvars)- let tp' = conT ''Cxt `appT` varT hvar `appT` varT gvar- `appT` varT avar `appT` varT bvar- let tp'' = arrowT `appT` (tp `appT` varT avar `appT` tp') `appT` tp'- forallT (map PlainTV $ hvar : gvar : avar : bvar : fvars)- (sequence cxt) tp''- genDecl n = [| In . $(varE $ mkName $ "inj" ++ show n) |]--deepInjectn :: Int -> Q [Dec]-deepInjectn n = do- let i = mkName ("deepInject" ++ show n)- let fvars = map (\n -> mkName $ 'f' : show n) [1..n]- let gvar = mkName "g"- let d = [funD i [clause [] (normalB $ genDecl n) []]]- sequence $ sigD i (genSig fvars gvar) : d- where genSig fvars gvar = do- let cxt = map (\f -> classP ''(:<:) [varT f, varT gvar]) fvars- let tp = foldl1 (\a f -> conT ''(:+:) `appT` f `appT` a)- (map varT fvars)- let cxt' = classP ''Difunctor [tp]- let tp' = conT ''CxtFun `appT` tp `appT` varT gvar- forallT (map PlainTV $ gvar : fvars) (sequence $ cxt' : cxt) tp'- genDecl n = [| appSigFun $(varE $ mkName $ "inj" ++ show n) |]
− src/Data/Comp/Param/Derive/Ordering.hs
@@ -1,93 +0,0 @@-{-# LANGUAGE TemplateHaskell, FlexibleInstances, IncoherentInstances,- ScopedTypeVariables #-}------------------------------------------------------------------------------------ |--- Module : Data.Comp.Param.Derive.Ordering--- Copyright : (c) 2011 Patrick Bahr, Tom Hvitved--- License : BSD3--- Maintainer : Tom Hvitved <hvitved@diku.dk>--- Stability : experimental--- Portability : non-portable (GHC Extensions)------ Automatically derive instances of @OrdD@.-------------------------------------------------------------------------------------module Data.Comp.Param.Derive.Ordering- (- OrdD(..),- makeOrdD- ) where--import Data.Comp.Param.FreshM hiding (Name)-import Data.Comp.Param.Ordering-import Data.Comp.Derive.Utils-import Language.Haskell.TH hiding (Cxt)-import Control.Monad (liftM)--{-| Derive an instance of 'OrdD' for a type constructor of any parametric- kind taking at least two arguments. -}-makeOrdD :: Name -> Q [Dec]-makeOrdD fname = do- -- Comments below apply to the example where name = T, args = [a,b,c], and- -- constrs = [(X,[c]), (Y,[a,c]), (Z,[b -> c])], i.e. the data type- -- declaration: T a b c = X c | Y a c | Z (b -> c)- TyConI (DataD _ name args constrs _) <- abstractNewtypeQ $ reify fname- -- coArg = c (covariant difunctor argument)- let coArg :: Name = tyVarBndrName $ last args- -- conArg = b (contravariant difunctor argument)- let conArg :: Name = tyVarBndrName $ last $ init args- -- argNames = [a]- let argNames = map (VarT . tyVarBndrName) (init $ init args)- -- compType = T a- let complType = foldl AppT (ConT name) argNames- -- classType = Difunctor (T a)- let classType = AppT (ConT ''OrdD) complType- -- constrs' = [(X,[c]), (Y,[a,c]), (Z,[b -> c])]- constrs' :: [(Name,[Type])] <- mapM normalConExp constrs- compareDDecl <- funD 'compareD (compareDClauses conArg coArg constrs')- let context = map (\arg -> ClassP ''Ord [arg]) argNames- return [InstanceD context classType [compareDDecl]]- where compareDClauses :: Name -> Name -> [(Name,[Type])] -> [ClauseQ]- compareDClauses _ _ [] = []- compareDClauses conArg coArg constrs = - let constrs' = constrs `zip` [1..]- constPairs = [(x,y)| x<-constrs', y <- constrs']- in map (genClause conArg coArg) constPairs- genClause conArg coArg ((c,n),(d,m))- | n == m = genEqClause conArg coArg c- | n < m = genLtClause c d- | otherwise = genGtClause c d- genEqClause :: Name -> Name -> (Name,[Type]) -> ClauseQ- genEqClause conArg coArg (constr, args) = do - varXs <- newNames (length args) "x"- varYs <- newNames (length args) "y"- let patX = ConP constr $ map VarP varXs- let patY = ConP constr $ map VarP varYs- body <- eqDBody conArg coArg (zip3 varXs varYs args)- return $ Clause [patX, patY] (NormalB body) []- eqDBody :: Name -> Name -> [(Name, Name, Type)] -> ExpQ- eqDBody conArg coArg x =- [|liftM compList (sequence $(listE $ map (eqDB conArg coArg) x))|]- eqDB :: Name -> Name -> (Name, Name, Type) -> ExpQ- eqDB conArg coArg (x, y, tp)- | not (containsType tp (VarT conArg)) &&- not (containsType tp (VarT coArg)) =- [| return $ compare $(varE x) $(varE y) |]- | otherwise =- case tp of- VarT a- | a == coArg -> [| pcompare $(varE x) $(varE y) |]- AppT (AppT ArrowT (VarT a)) _- | a == conArg ->- [| withName (\v -> pcompare ($(varE x) v) ($(varE y) v)) |]- SigT tp' _ ->- eqDB conArg coArg (x, y, tp')- _ ->- if containsType tp (VarT conArg) then- [| compareD $(varE x) $(varE y) |]- else- [| pcompare $(varE x) $(varE y) |]- genLtClause (c, _) (d, _) =- clause [recP c [], recP d []] (normalB [| return LT |]) []- genGtClause (c, _) (d, _) =- clause [recP c [], recP d []] (normalB [| return GT |]) []
− src/Data/Comp/Param/Derive/Projections.hs
@@ -1,101 +0,0 @@-{-# LANGUAGE TemplateHaskell, GADTs #-}------------------------------------------------------------------------------------ |--- Module : Data.Comp.Param.Derive.Projections--- Copyright : (c) 2011 Patrick Bahr, Tom Hvitved--- License : BSD3--- Maintainer : Tom Hvitved <hvitved@diku.dk>--- Stability : experimental--- Portability : non-portable (GHC Extensions)------ Derive functions for signature projections.--------------------------------------------------------------------------------------module Data.Comp.Param.Derive.Projections- (- projn,- projectn,- deepProjectn- ) where--import Language.Haskell.TH hiding (Cxt)-import Control.Monad (liftM)-import Data.Comp.Param.Ditraversable (Ditraversable)-import Data.Comp.Param.Term-import Data.Comp.Param.Algebra (appTSigFunM')-import Data.Comp.Param.Ops ((:+:)(..), (:<:)(..))--projn :: Int -> Q [Dec]-projn n = do- let p = mkName $ "proj" ++ show n- let gvars = map (\n -> mkName $ 'g' : show n) [1..n]- let avar = mkName "a"- let bvar = mkName "b"- let xvar = mkName "x"- let d = [funD p [clause [varP xvar] (normalB $ genDecl xvar gvars avar bvar) []]]- sequence $ (sigD p $ genSig gvars avar bvar) : d- where genSig gvars avar bvar = do- let fvar = mkName "f"- let cxt = map (\g -> classP ''(:<:) [varT g, varT fvar]) gvars- let tp = foldl1 (\a g -> conT ''(:+:) `appT` g `appT` a)- (map varT gvars)- let tp' = arrowT `appT` (varT fvar `appT` varT avar `appT`- varT bvar)- `appT` (conT ''Maybe `appT`- (tp `appT` varT avar `appT` varT bvar))- forallT (map PlainTV $ fvar : avar : bvar : gvars)- (sequence cxt) tp'- genDecl x [g] a b =- [| liftM inj (proj $(varE x)- :: Maybe ($(varT g `appT` varT a `appT` varT b))) |]- genDecl x (g:gs) a b =- [| case (proj $(varE x)- :: Maybe ($(varT g `appT` varT a `appT` varT b))) of- Just y -> Just $ inj y- _ -> $(genDecl x gs a b) |]- genDecl _ _ _ _ = error "genDecl called with empty list"--projectn :: Int -> Q [Dec]-projectn n = do- let p = mkName ("project" ++ show n)- let gvars = map (\n -> mkName $ 'g' : show n) [1..n]- let avar = mkName "a"- let bvar = mkName "b"- let xvar = mkName "x"- let d = [funD p [clause [varP xvar] (normalB $ genDecl xvar n) []]]- sequence $ (sigD p $ genSig gvars avar bvar) : d- where genSig gvars avar bvar = do- let fvar = mkName "f"- let hvar = mkName "h"- let cxt = map (\g -> classP ''(:<:) [varT g, varT fvar]) gvars- let tp = foldl1 (\a g -> conT ''(:+:) `appT` g `appT` a)- (map varT gvars)- let tp' = conT ''Cxt `appT` varT hvar `appT` varT fvar- `appT` varT avar `appT` varT bvar- let tp'' = arrowT `appT` tp'- `appT` (conT ''Maybe `appT`- (tp `appT` varT avar `appT` tp'))- forallT (map PlainTV $ hvar : fvar : avar : bvar : gvars)- (sequence cxt) tp''- genDecl x n = [| case $(varE x) of- Hole _ -> Nothing- Var _ -> Nothing- In t -> $(varE $ mkName $ "proj" ++ show n) t |]--deepProjectn :: Int -> Q [Dec]-deepProjectn n = do- let p = mkName ("deepProject" ++ show n)- let gvars = map (\n -> mkName $ 'g' : show n) [1..n]- let d = [funD p [clause [] (normalB $ genDecl n) []]]- sequence $ (sigD p $ genSig gvars) : d- where genSig gvars = do- let fvar = mkName "f"- let cxt = map (\g -> classP ''(:<:) [varT g, varT fvar]) gvars- let tp = foldl1 (\a g -> conT ''(:+:) `appT` g `appT` a)- (map varT gvars)- let cxt' = classP ''Ditraversable [tp]- let tp' = arrowT `appT` (conT ''Term `appT` varT fvar)- `appT` (conT ''Maybe `appT` (conT ''Term `appT` tp))- forallT (map PlainTV $ fvar : gvars) (sequence $ cxt' : cxt) tp'- genDecl n = [| appTSigFunM' $(varE $ mkName $ "proj" ++ show n) |]
− src/Data/Comp/Param/Derive/Show.hs
@@ -1,92 +0,0 @@-{-# LANGUAGE TemplateHaskell, FlexibleInstances, IncoherentInstances,- ScopedTypeVariables, UndecidableInstances #-}------------------------------------------------------------------------------------ |--- Module : Data.Comp.Param.Derive.Show--- Copyright : (c) 2011 Patrick Bahr, Tom Hvitved--- License : BSD3--- Maintainer : Tom Hvitved <hvitved@diku.dk>--- Stability : experimental--- Portability : non-portable (GHC Extensions)------ Automatically derive instances of @ShowD@.-------------------------------------------------------------------------------------module Data.Comp.Param.Derive.Show- (- ShowD(..),- makeShowD- ) where--import Data.Comp.Derive.Utils-import Data.Comp.Param.FreshM hiding (Name)-import qualified Data.Comp.Param.FreshM as FreshM-import Control.Monad-import Language.Haskell.TH hiding (Cxt, match)-import qualified Data.Traversable as T--{-| Signature printing. An instance @ShowD f@ gives rise to an instance- @Show (Term f)@. -}-class ShowD f where- showD :: f FreshM.Name (FreshM String) -> FreshM String--newtype Dummy = Dummy String--instance Show Dummy where- show (Dummy s) = s--{-| Derive an instance of 'ShowD' for a type constructor of any parametric- kind taking at least two arguments. -}-makeShowD :: Name -> Q [Dec]-makeShowD fname = do- -- Comments below apply to the example where name = T, args = [a,b,c], and- -- constrs = [(X,[c]), (Y,[a,c]), (Z,[b -> c])], i.e. the data type- -- declaration: T a b c = X c | Y a c | Z (b -> c)- TyConI (DataD _ name args constrs _) <- abstractNewtypeQ $ reify fname- -- coArg = c (covariant difunctor argument)- let coArg :: Name = tyVarBndrName $ last args- -- conArg = b (contravariant difunctor argument)- let conArg :: Name = tyVarBndrName $ last $ init args- -- argNames = [a]- let argNames = map (VarT . tyVarBndrName) (init $ init args)- -- compType = T a- let complType = foldl AppT (ConT name) argNames- -- classType = Difunctor (T a)- let classType = AppT (ConT ''ShowD) complType- -- constrs' = [(X,[c]), (Y,[a,c]), (Z,[b -> c])]- constrs' :: [(Name,[Type])] <- mapM normalConExp constrs- showDDecl <- funD 'showD (map (showDClause conArg coArg) constrs')- let context = map (\arg -> ClassP ''Show [arg]) argNames- return [InstanceD context classType [showDDecl]]- where showDClause :: Name -> Name -> (Name,[Type]) -> ClauseQ- showDClause conArg coArg (constr, args) = do- varXs <- newNames (length args) "x"- -- Pattern for the constructor- let patx = ConP constr $ map VarP varXs- body <- showDBody (nameBase constr) conArg coArg (zip varXs args)- return $ Clause [patx] (NormalB body) []- showDBody :: String -> Name -> Name -> [(Name, Type)] -> ExpQ- showDBody constr conArg coArg x =- [|liftM (unwords . (constr :) .- map (\x -> if elem ' ' x then "(" ++ x ++ ")" else x))- (sequence $(listE $ map (showDB conArg coArg) x))|]- showDB :: Name -> Name -> (Name, Type) -> ExpQ- showDB conArg coArg (x, tp)- | not (containsType tp (VarT conArg)) &&- not (containsType tp (VarT coArg)) =- [| return $ show $(varE x) |]- | otherwise =- case tp of- VarT a- | a == coArg -> [| $(varE x) |]- AppT (AppT ArrowT (VarT a)) _- | a == conArg ->- [| withName (\v -> do body <- $(varE x) v;- return $ "\\" ++ show v ++ " -> " ++ body) |]- SigT tp' _ ->- showDB conArg coArg (x, tp')- _ ->- if containsType tp (VarT conArg) then- [| showD $(varE x) |]- else- [| liftM show $ T.mapM (liftM Dummy) $(varE x) |]
− src/Data/Comp/Param/Derive/SmartAConstructors.hs
@@ -1,47 +0,0 @@-{-# LANGUAGE TemplateHaskell #-}------------------------------------------------------------------------------------ |--- Module : Data.Comp.Param.Derive.SmartAConstructors--- Copyright : (c) 2011 Patrick Bahr, Tom Hvitved--- License : BSD3--- Maintainer : Tom Hvitved <hvitved@diku.dk>--- Stability : experimental--- Portability : non-portable (GHC Extensions)------ Automatically derive smart constructors with annotations for difunctors.--------------------------------------------------------------------------------------module Data.Comp.Param.Derive.SmartAConstructors - (- smartAConstructors- ) where--import Language.Haskell.TH hiding (Cxt)-import Data.Comp.Derive.Utils-import Data.Comp.Param.Ops-import Data.Comp.Param.Term-import Data.Comp.Param.Difunctor--import Control.Monad--{-| Derive smart constructors with annotations for a difunctor. The smart- constructors are similar to the ordinary constructors, but a- 'injectA . dimap Var id' is automatically inserted. -}-smartAConstructors :: Name -> Q [Dec]-smartAConstructors fname = do- TyConI (DataD _cxt tname targs constrs _deriving) <- abstractNewtypeQ $ reify fname- let cons = map abstractConType constrs- liftM concat $ mapM (genSmartConstr (map tyVarBndrName targs) tname) cons- where genSmartConstr targs tname (name, args) = do- let bname = nameBase name- genSmartConstr' targs tname (mkName $ "iA" ++ bname) name args- genSmartConstr' targs tname sname name args = do- varNs <- newNames args "x"- varPr <- newName "_p"- let pats = map varP (varPr : varNs)- vars = map varE varNs- val = appE [|injectA $(varE varPr)|] $- appE [|inj . dimap Var id|] $ foldl appE (conE name) vars- function = [funD sname [clause pats (normalB [|In $val|]) []]]- sequence function
− src/Data/Comp/Param/Derive/SmartConstructors.hs
@@ -1,62 +0,0 @@-{-# LANGUAGE TemplateHaskell #-}------------------------------------------------------------------------------------ |--- Module : Data.Comp.Param.Derive.SmartConstructors--- Copyright : (c) 2011 Patrick Bahr, Tom Hvitved--- License : BSD3--- Maintainer : Tom Hvitved <hvitved@diku.dk>--- Stability : experimental--- Portability : non-portable (GHC Extensions)------ Automatically derive smart constructors for difunctors.--------------------------------------------------------------------------------------module Data.Comp.Param.Derive.SmartConstructors - (- smartConstructors- ) where--import Language.Haskell.TH hiding (Cxt)-import Data.Comp.Derive.Utils-import Data.Comp.Param.Sum-import Data.Comp.Param.Term-import Data.Comp.Param.Difunctor-import Control.Monad--{-| Derive smart constructors for a difunctor. The smart constructors are- similar to the ordinary constructors, but a 'inject . dimap Var id' is- automatically inserted. -}-smartConstructors :: Name -> Q [Dec]-smartConstructors fname = do- TyConI (DataD _cxt tname targs constrs _deriving) <- abstractNewtypeQ $ reify fname- let cons = map abstractConType constrs- liftM concat $ mapM (genSmartConstr (map tyVarBndrName targs) tname) cons- where genSmartConstr targs tname (name, args) = do- let bname = nameBase name- genSmartConstr' targs tname (mkName $ 'i' : bname) name args- genSmartConstr' targs tname sname name args = do- varNs <- newNames args "x"- let pats = map varP varNs- vars = map varE varNs- val = foldl appE (conE name) vars- sig = genSig targs tname sname args- function = [funD sname [clause pats (normalB [|inject (dimap Var id $val)|]) []]]- sequence $ sig ++ function- genSig targs tname sname 0 = (:[]) $ do- hvar <- newName "h"- fvar <- newName "f"- avar <- newName "a"- bvar <- newName "b"- let targs' = init $ init targs- vars = hvar:fvar:avar:bvar:targs'- h = varT hvar- f = varT fvar- a = varT avar- b = varT bvar- ftype = foldl appT (conT tname) (map varT targs')- constr = classP ''(:<:) [ftype, f]- typ = foldl appT (conT ''Cxt) [h, f, a, b]- typeSig = forallT (map PlainTV vars) (sequence [constr]) typ- sigD sname typeSig- genSig _ _ _ _ = []
− src/Data/Comp/Param/Desugar.hs
@@ -1,45 +0,0 @@-{-# LANGUAGE TemplateHaskell, MultiParamTypeClasses, FlexibleInstances,- UndecidableInstances, OverlappingInstances, Rank2Types, TypeOperators #-}------------------------------------------------------------------------------------ |--- Module : Data.Comp.Param.Desugar--- Copyright : (c) 2011 Patrick Bahr, Tom Hvitved--- License : BSD3--- Maintainer : Tom Hvitved <hvitved@diku.dk>--- Stability : experimental--- Portability : non-portable (GHC Extensions)------ This modules defines the 'Desugar' type class for desugaring of terms.--------------------------------------------------------------------------------------module Data.Comp.Param.Desugar where--import Data.Comp.Param----- |The desugaring term homomorphism.-class (Difunctor f, Difunctor g) => Desugar f g where- desugHom :: Hom f g- desugHom = desugHom' . fmap Hole- desugHom' :: f a (Cxt h g a b) -> Cxt h g a b- desugHom' x = appCxt (desugHom x)---- We make the lifting to sums explicit in order to make the Desugar--- class work with the default instance declaration further below.-instance (Desugar f h, Desugar g h) => Desugar (f :+: g) h where- desugHom = caseD desugHom desugHom---- |Desugar a term.-desugar :: Desugar f g => Term f -> Term g-{-# INLINE desugar #-}-desugar (Term t) = Term (appHom desugHom t)---- |Lift desugaring to annotated terms.-desugarA :: (Difunctor f', Difunctor g', DistAnn f p f', DistAnn g p g',- Desugar f g) => Term f' -> Term g'-desugarA (Term t) = Term (appHom (propAnn desugHom) t)---- |Default desugaring instance.-instance (Difunctor f, Difunctor g, f :<: g) => Desugar f g where- desugHom = simpCxt . inj
− src/Data/Comp/Param/Difunctor.hs
@@ -1,36 +0,0 @@-{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances #-}------------------------------------------------------------------------------------ |--- Module : Data.Comp.Param.Difunctor--- Copyright : (c) 2011 Patrick Bahr, Tom Hvitved--- License : BSD3--- Maintainer : Tom Hvitved <hvitved@diku.dk>--- Stability : experimental--- Portability : non-portable (GHC Extensions)------ This module defines difunctors (Meijer, Hutton, FPCA '95), i.e. binary type--- constructors that are contravariant in the first argument and covariant in--- the second argument.--------------------------------------------------------------------------------------module Data.Comp.Param.Difunctor- (- difmap,- Difunctor(..)- ) where---- | This class represents difunctors, i.e. binary type constructors that are--- contravariant in the first argument and covariant in the second argument.-class Difunctor f where- dimap :: (a -> b) -> (c -> d) -> f b c -> f a d--{-| The canonical example of a difunctor. -}-instance Difunctor (->) where- dimap f g h = g . h . f--difmap :: Difunctor f => (a -> b) -> f c a -> f c b-difmap = dimap id--instance Difunctor f => Functor (f a) where- fmap = difmap
− src/Data/Comp/Param/Ditraversable.hs
@@ -1,28 +0,0 @@-{-# LANGUAGE MultiParamTypeClasses, FlexibleContexts #-}------------------------------------------------------------------------------------ |--- Module : Data.Comp.Param.Ditraversable--- Copyright : (c) 2011 Patrick Bahr, Tom Hvitved--- License : BSD3--- Maintainer : Tom Hvitved <hvitved@diku.dk>--- Stability : experimental--- Portability : non-portable (GHC Extensions)------ This module defines traversable difunctors.--------------------------------------------------------------------------------------module Data.Comp.Param.Ditraversable- (- Ditraversable(..)- ) where--import Data.Comp.Param.Difunctor--{-| Difunctors representing data structures that can be traversed from left to- right. -}-class Difunctor f => Ditraversable f where- dimapM :: Monad m => (b -> m c) -> f a b -> m (f a c)- dimapM f = disequence . fmap f- disequence :: Monad m => f a (m b) -> m (f a b)- disequence = dimapM id
− src/Data/Comp/Param/Equality.hs
@@ -1,67 +0,0 @@-{-# LANGUAGE TypeOperators, TypeSynonymInstances, FlexibleInstances,- UndecidableInstances, IncoherentInstances, GADTs #-}------------------------------------------------------------------------------------ |--- Module : Data.Comp.Param.Equality--- Copyright : (c) 2011 Patrick Bahr, Tom Hvitved--- License : BSD3--- Maintainer : Tom Hvitved <hvitved@diku.dk>--- Stability : experimental--- Portability : non-portable (GHC Extensions)------ This module defines equality for signatures, which lifts to equality for--- terms.-------------------------------------------------------------------------------------module Data.Comp.Param.Equality- (- PEq(..),- EqD(..)- ) where--import Data.Comp.Param.Term-import Data.Comp.Param.Sum-import Data.Comp.Param.Ops-import Data.Comp.Param.Difunctor-import Data.Comp.Param.FreshM-import Control.Monad (liftM)---- |Equality on parametric values. The equality test is performed inside the--- 'FreshM' monad for generating fresh identifiers.-class PEq a where- peq :: a -> a -> FreshM Bool--instance PEq a => PEq [a] where- peq l1 l2- | length l1 /= length l2 = return False- | otherwise = liftM or $ mapM (uncurry peq) $ zip l1 l2--instance Eq a => PEq a where- peq x y = return $ x == y--{-| Signature equality. An instance @EqD f@ gives rise to an instance- @Eq (Term f)@. The equality test is performed inside the 'FreshM' monad for- generating fresh identifiers. -}-class EqD f where- eqD :: PEq a => f Name a -> f Name a -> FreshM Bool--{-| 'EqD' is propagated through sums. -}-instance (EqD f, EqD g) => EqD (f :+: g) where- eqD (Inl x) (Inl y) = eqD x y- eqD (Inr x) (Inr y) = eqD x y- eqD _ _ = return False--{-| From an 'EqD' difunctor an 'Eq' instance of the corresponding term type can- be derived. -}-instance EqD f => EqD (Cxt h f) where- eqD (In e1) (In e2) = eqD e1 e2- eqD (Hole h1) (Hole h2) = peq h1 h2- eqD (Var p1) (Var p2) = peq p1 p2- eqD _ _ = return False--instance (EqD f, PEq a) => PEq (Cxt h f Name a) where- peq = eqD--{-| Equality on terms. -}-instance (Difunctor f, EqD f) => Eq (Term f) where- (==) (Term x) (Term y) = evalFreshM $ eqD x y
− src/Data/Comp/Param/FreshM.hs
@@ -1,49 +0,0 @@-{-# LANGUAGE GeneralizedNewtypeDeriving #-}------------------------------------------------------------------------------------ |--- Module : Data.Comp.Param.FreshM--- Copyright : (c) 2011 Patrick Bahr, Tom Hvitved--- License : BSD3--- Maintainer : Tom Hvitved <hvitved@diku.dk>--- Stability : experimental--- Portability : non-portable (GHC Extensions)------ This module defines a monad for generating fresh, abstract names, useful--- e.g. for defining equality on terms.-------------------------------------------------------------------------------------module Data.Comp.Param.FreshM- (- FreshM,- Name,- withName,- evalFreshM- ) where--import Control.Monad.Reader---- |Monad for generating fresh (abstract) names.-newtype FreshM a = FreshM{unFreshM :: Reader Int a}- deriving Monad---- |Abstract notion of a name (the constructor is hidden).-newtype Name = Name Int- deriving Eq--instance Show Name where- show (Name x) = names !! x- where baseNames = ['a'..'z']- names = map (:[]) baseNames ++ names' 1- names' n = map (: show n) baseNames ++ names' (n + 1)--instance Ord Name where- compare (Name x) (Name y) = compare x y---- |Run the given computation with the next available name.-withName :: (Name -> FreshM a) -> FreshM a-withName m = do name <- FreshM (asks Name)- FreshM $ local ((+) 1) $ unFreshM $ m name---- |Evaluate a computation that uses fresh names.-evalFreshM :: FreshM a -> a-evalFreshM (FreshM m) = runReader m 0
− src/Data/Comp/Param/Ops.hs
@@ -1,127 +0,0 @@-{-# LANGUAGE TypeOperators, MultiParamTypeClasses, FunctionalDependencies,- FlexibleInstances, UndecidableInstances, IncoherentInstances #-}------------------------------------------------------------------------------------ |--- Module : Data.Comp.Param.Ops--- Copyright : (c) 2011 Patrick Bahr, Tom Hvitved--- License : BSD3--- Maintainer : Tom Hvitved <hvitved@diku.dk>--- Stability : experimental--- Portability : non-portable (GHC Extensions)------ This module provides operators on difunctors.--------------------------------------------------------------------------------------module Data.Comp.Param.Ops where--import Data.Comp.Param.Difunctor-import Data.Comp.Param.Ditraversable-import Control.Monad (liftM)----- Sums-infixr 6 :+:---- |Formal sum of signatures (difunctors).-data (f :+: g) a b = Inl (f a b)- | Inr (g a b)--{-| Utility function to case on a difunctor sum, without exposing the internal- representation of sums. -}-caseD :: (f a b -> c) -> (g a b -> c) -> (f :+: g) a b -> c-caseD f g x = case x of- Inl x -> f x- Inr x -> g x--instance (Difunctor f, Difunctor g) => Difunctor (f :+: g) where- dimap f g (Inl e) = Inl (dimap f g e)- dimap f g (Inr e) = Inr (dimap f g e)--instance (Ditraversable f, Ditraversable g) => Ditraversable (f :+: g) where- dimapM f (Inl e) = Inl `liftM` dimapM f e- dimapM f (Inr e) = Inr `liftM` dimapM f e- disequence (Inl e) = Inl `liftM` disequence e- disequence (Inr e) = Inr `liftM` disequence e---- | Signature containment relation for automatic injections. The left-hand must--- be an atomic signature, where as the right-hand side must have a list-like--- structure. Examples include @f :<: f :+: g@ and @g :<: f :+: (g :+: h)@,--- non-examples include @f :+: g :<: f :+: (g :+: h)@ and--- @f :<: (f :+: g) :+: h@.-class sub :<: sup where- inj :: sub a b -> sup a b- proj :: sup a b -> Maybe (sub a b)--instance (:<:) f f where- inj = id- proj = Just--instance (:<:) f (f :+: g) where- inj = Inl- proj (Inl x) = Just x- proj (Inr _) = Nothing--instance (f :<: g) => (:<:) f (h :+: g) where- inj = Inr . inj- proj (Inr x) = proj x- proj (Inl _) = Nothing----- Products-infixr 8 :*:---- |Formal product of signatures (difunctors).-data (f :*: g) a b = f a b :*: g a b--ffst :: (f :*: g) a b -> f a b-ffst (x :*: _) = x--fsnd :: (f :*: g) a b -> g a b-fsnd (_ :*: x) = x----- Constant Products-infixr 7 :&:--{-| This data type adds a constant product to a signature. -}-data (f :&: p) a b = f a b :&: p--instance Difunctor f => Difunctor (f :&: p) where- dimap f g (v :&: c) = dimap f g v :&: c--instance Ditraversable f => Ditraversable (f :&: p) where- dimapM f (v :&: c) = liftM (:&: c) (dimapM f v)- disequence (v :&: c) = liftM (:&: c) (disequence v)--{-| This class defines how to distribute an annotation over a sum of- signatures. -}-class DistAnn s p s' | s' -> s, s' -> p where- {-| Inject an annotation over a signature. -}- injectA :: p -> s a b -> s' a b- {-| Project an annotation from a signature. -}- projectA :: s' a b -> (s a b, p)--class RemA s s' | s -> s' where- {-| Remove annotations from a signature. -}- remA :: s a b -> s' a b--instance (RemA s s') => RemA (f :&: p :+: s) (f :+: s') where- remA (Inl (v :&: _)) = Inl v- remA (Inr v) = Inr $ remA v--instance RemA (f :&: p) f where- remA (v :&: _) = v--instance DistAnn f p (f :&: p) where- injectA c v = v :&: c-- projectA (v :&: p) = (v,p)--instance (DistAnn s p s') => DistAnn (f :+: s) p ((f :&: p) :+: s') where- injectA c (Inl v) = Inl (v :&: c)- injectA c (Inr v) = Inr $ injectA c v-- projectA (Inl (v :&: p)) = (Inl v,p)- projectA (Inr v) = let (v',p) = projectA v- in (Inr v',p)
− src/Data/Comp/Param/Ordering.hs
@@ -1,77 +0,0 @@-{-# LANGUAGE TypeOperators, TypeSynonymInstances, FlexibleInstances,- UndecidableInstances, IncoherentInstances, GADTs #-}------------------------------------------------------------------------------------ |--- Module : Data.Comp.Param.Ordering--- Copyright : (c) 2011 Patrick Bahr, Tom Hvitved--- License : BSD3--- Maintainer : Tom Hvitved <hvitved@diku.dk>--- Stability : experimental--- Portability : non-portable (GHC Extensions)------ This module defines ordering of signatures, which lifts to ordering of--- terms and contexts.-------------------------------------------------------------------------------------module Data.Comp.Param.Ordering- (- POrd(..),- OrdD(..),- compList- ) where--import Data.Comp.Param.Term-import Data.Comp.Param.Sum-import Data.Comp.Param.Ops-import Data.Comp.Param.Difunctor-import Data.Comp.Param.FreshM-import Data.Comp.Param.Equality-import Data.Maybe (fromMaybe)-import Data.List (find)-import Control.Monad (liftM)---- |Ordering of parametric values.-class PEq a => POrd a where- pcompare :: a -> a -> FreshM Ordering--instance POrd a => POrd [a] where- pcompare l1 l2- | length l1 < length l2 = return LT- | length l1 > length l2 = return GT- | otherwise = liftM compList $ mapM (uncurry pcompare) $ zip l1 l2--compList :: [Ordering] -> Ordering-compList = fromMaybe EQ . find (/= EQ)--instance Ord a => POrd a where- pcompare x y = return $ compare x y--{-| Signature ordering. An instance @OrdD f@ gives rise to an instance- @Ord (Term f)@. -}-class EqD f => OrdD f where- compareD :: POrd a => f Name a -> f Name a -> FreshM Ordering--{-| 'OrdD' is propagated through sums. -}-instance (OrdD f, OrdD g) => OrdD (f :+: g) where- compareD (Inl x) (Inl y) = compareD x y- compareD (Inl _) (Inr _) = return LT- compareD (Inr x) (Inr y) = compareD x y- compareD (Inr _) (Inl _) = return GT--{-| From an 'OrdD' difunctor an 'Ord' instance of the corresponding term type- can be derived. -}-instance OrdD f => OrdD (Cxt h f) where- compareD (In e1) (In e2) = compareD e1 e2- compareD (Hole h1) (Hole h2) = pcompare h1 h2- compareD (Var p1) (Var p2) = pcompare p1 p2- compareD (In _) _ = return LT- compareD (Hole _) (In _) = return GT- compareD (Hole _) (Var _) = return LT- compareD (Var _) _ = return GT--instance (OrdD f, POrd a) => POrd (Cxt h f Name a) where- pcompare = compareD--{-| Ordering of terms. -}-instance (Difunctor f, OrdD f) => Ord (Term f) where- compare (Term x) (Term y) = evalFreshM $ compareD x y
− src/Data/Comp/Param/Show.hs
@@ -1,41 +0,0 @@-{-# LANGUAGE TypeOperators, FlexibleInstances, TypeSynonymInstances,- IncoherentInstances, UndecidableInstances, TemplateHaskell, GADTs #-}------------------------------------------------------------------------------------ |--- Module : Data.Comp.Param.Show--- Copyright : (c) 2011 Patrick Bahr, Tom Hvitved--- License : BSD3--- Maintainer : Tom Hvitved <hvitved@diku.dk>--- Stability : experimental--- Portability : non-portable (GHC Extensions)------ This module defines showing of signatures, which lifts to showing of terms.-------------------------------------------------------------------------------------module Data.Comp.Param.Show- (- ShowD(..)- ) where--import Data.Comp.Param.Term-import Data.Comp.Param.Ops-import Data.Comp.Param.Derive-import Data.Comp.Param.FreshM---- Lift ShowD to sums-$(derive [liftSum] [''ShowD])--{-| From an 'ShowD' difunctor an 'ShowD' instance of the corresponding term type- can be derived. -}-instance (Difunctor f, ShowD f) => ShowD (Cxt h f) where- showD (In t) = showD $ fmap showD t- showD (Hole h) = h- showD (Var p) = return $ show p--{-| Printing of terms. -}-instance (Difunctor f, ShowD f) => Show (Term f) where- show = evalFreshM . showD . toCxt . unTerm--instance (ShowD f, Show p) => ShowD (f :&: p) where- showD (x :&: p) = do sx <- showD x- return $ sx ++ " :&: " ++ show p
− src/Data/Comp/Param/Sum.hs
@@ -1,186 +0,0 @@-{-# LANGUAGE TypeOperators, MultiParamTypeClasses, IncoherentInstances,- FlexibleInstances, FlexibleContexts, GADTs, TypeSynonymInstances,- ScopedTypeVariables, TemplateHaskell, Rank2Types #-}------------------------------------------------------------------------------------ |--- Module : Data.Comp.Param.Sum--- Copyright : (c) 2011 Patrick Bahr, Tom Hvitved--- License : BSD3--- Maintainer : Tom Hvitved <hvitved@diku.dk>--- Stability : experimental--- Portability : non-portable (GHC Extensions)------ This module provides the infrastructure to extend signatures.--------------------------------------------------------------------------------------module Data.Comp.Param.Sum- (- (:<:),- (:+:),- caseD,-- -- * Projections for Signatures and Terms- proj,- proj2,- proj3,- proj4,- proj5,- proj6,- proj7,- proj8,- proj9,- proj10,- project,- project2,- project3,- project4,- project5,- project6,- project7,- project8,- project9,- project10,- deepProject,- deepProject2,- deepProject3,- deepProject4,- deepProject5,- deepProject6,- deepProject7,- deepProject8,- deepProject9,- deepProject10,-- -- * Injections for Signatures and Terms- inj,- inj2,- inj3,- inj4,- inj5,- inj6,- inj7,- inj8,- inj9,- inj10,- inject,- inject',- inject2,- inject3,- inject4,- inject5,- inject6,- inject7,- inject8,- inject9,- inject10,- deepInject,- deepInject2,- deepInject3,- deepInject4,- deepInject5,- deepInject6,- deepInject7,- deepInject8,- deepInject9,- deepInject10,-- injectCxt,- liftCxt- ) where--import Prelude hiding (sequence)-import Control.Monad hiding (sequence)-import Data.Comp.Param.Term-import Data.Comp.Param.Algebra-import Data.Comp.Param.Ops-import Data.Comp.Param.Derive.Projections-import Data.Comp.Param.Derive.Injections-import Data.Comp.Param.Difunctor-import Data.Comp.Param.Ditraversable--$(liftM concat $ mapM projn [2..10])---- |Project the outermost layer of a term to a sub signature. If the signature--- @g@ is compound of /n/ atomic signatures, use @project@/n/ instead.-project :: (g :<: f) => Cxt h f a b -> Maybe (g a (Cxt h f a b))-project (In t) = proj t-project (Hole _) = Nothing-project (Var _) = Nothing--$(liftM concat $ mapM projectn [2..10])---- | Tries to coerce a term/context to a term/context over a sub-signature. If--- the signature @g@ is compound of /n/ atomic signatures, use--- @deepProject@/n/ instead.-deepProject :: (Ditraversable g, g :<: f) => Term f -> Maybe (Term g)-{-# INLINE deepProject #-}-deepProject = appTSigFunM' proj--$(liftM concat $ mapM deepProjectn [2..10])-{-# INLINE deepProject2 #-}-{-# INLINE deepProject3 #-}-{-# INLINE deepProject4 #-}-{-# INLINE deepProject5 #-}-{-# INLINE deepProject6 #-}-{-# INLINE deepProject7 #-}-{-# INLINE deepProject8 #-}-{-# INLINE deepProject9 #-}-{-# INLINE deepProject10 #-}--$(liftM concat $ mapM injn [2..10])---- |Inject a term where the outermost layer is a sub signature. If the signature--- @g@ is compound of /n/ atomic signatures, use @inject@/n/ instead.-inject :: (g :<: f) => g a (Cxt h f a b) -> Cxt h f a b-inject = In . inj---- |Inject a term where the outermost layer is a sub signature. If the signature--- @g@ is compound of /n/ atomic signatures, use @inject@/n/ instead.-inject' :: (Difunctor g, g :<: f) => g (Cxt h f a b) (Cxt h f a b) -> Cxt h f a b-inject' = inject . dimap Var id--$(liftM concat $ mapM injectn [2..10])---- |Inject a term over a sub signature to a term over larger signature. If the--- signature @g@ is compound of /n/ atomic signatures, use @deepInject@/n/--- instead.-deepInject :: (Difunctor g, g :<: f) => Term g -> Term f-{-# INLINE deepInject #-}-deepInject (Term t) = Term (appSigFun inj t)--$(liftM concat $ mapM deepInjectn [2..10])-{-# INLINE deepInject2 #-}-{-# INLINE deepInject3 #-}-{-# INLINE deepInject4 #-}-{-# INLINE deepInject5 #-}-{-# INLINE deepInject6 #-}-{-# INLINE deepInject7 #-}-{-# INLINE deepInject8 #-}-{-# INLINE deepInject9 #-}-{-# INLINE deepInject10 #-}--{-| This function injects a whole context into another context. -}-injectCxt :: (Difunctor g, g :<: f) => Cxt h g a (Cxt h f a b) -> Cxt h f a b-injectCxt (In t) = inject $ difmap injectCxt t-injectCxt (Hole x) = x-injectCxt (Var p) = Var p--{-| This function lifts the given functor to a context. -}-liftCxt :: (Difunctor f, g :<: f) => g a b -> Cxt Hole f a b-liftCxt g = simpCxt $ inj g--instance (Show (f a b), Show (g a b)) => Show ((f :+: g) a b) where- show (Inl v) = show v- show (Inr v) = show v--instance (Ord (f a b), Ord (g a b)) => Ord ((f :+: g) a b) where- compare (Inl _) (Inr _) = LT- compare (Inr _) (Inl _) = GT- compare (Inl x) (Inl y) = compare x y- compare (Inr x) (Inr y) = compare x y--instance (Eq (f a b), Eq (g a b)) => Eq ((f :+: g) a b) where- (Inl x) == (Inl y) = x == y- (Inr x) == (Inr y) = x == y - _ == _ = False
− src/Data/Comp/Param/Term.hs
@@ -1,109 +0,0 @@-{-# LANGUAGE EmptyDataDecls, GADTs, KindSignatures, Rank2Types,- MultiParamTypeClasses, TypeSynonymInstances, FlexibleInstances #-}------------------------------------------------------------------------------------ |--- Module : Data.Comp.Param.Term--- Copyright : (c) 2011 Patrick Bahr, Tom Hvitved--- License : BSD3--- Maintainer : Tom Hvitved <hvitved@diku.dk>--- Stability : experimental--- Portability : non-portable (GHC Extensions)------ This module defines the central notion of /parametrised terms/ and their--- generalisation to parametrised contexts.--------------------------------------------------------------------------------------module Data.Comp.Param.Term- (- Cxt(..),- Hole,- NoHole,- Term(..),- Trm,- Context,- simpCxt,- toCxt,- cxtMap,- ParamFunctor(..)- ) where--import Prelude hiding (mapM, sequence, foldl, foldl1, foldr, foldr1)-import Data.Comp.Param.Difunctor-import Unsafe.Coerce (unsafeCoerce)--import Data.Maybe (fromJust)--{-| This data type represents contexts over a signature. Contexts are terms- containing zero or more holes, and zero or more parameters. The first- parameter is a phantom type indicating whether the context has holes. The- second paramater is the signature of the context, in the form of a- "Data.Comp.Param.Difunctor". The third parameter is the type of parameters,- and the fourth parameter is the type of holes. -}-data Cxt :: * -> (* -> * -> *) -> * -> * -> * where- In :: f a (Cxt h f a b) -> Cxt h f a b- Hole :: b -> Cxt Hole f a b- Var :: a -> Cxt h f a b--{-| Phantom type used to define 'Context'. -}-data Hole--{-| Phantom type used to define 'Term'. -}-data NoHole--{-| A context may contain holes. -}-type Context = Cxt Hole--{-| \"Preterms\" -}-type Trm f a = Cxt NoHole f a ()--{-| A term is a context with no holes, where all occurrences of the- contravariant parameter is fully parametric. -}-newtype Term f = Term{unTerm :: forall a. Trm f a}--{-| Convert a difunctorial value into a context. -}-simpCxt :: Difunctor f => f a b -> Cxt Hole f a b-{-# INLINE simpCxt #-}-simpCxt = In . difmap Hole--toCxt :: Difunctor f => Trm f a -> Cxt h f a b-{-# INLINE toCxt #-}-toCxt = unsafeCoerce---- | This combinator maps a function over a context by applying the--- function to each hole.-cxtMap :: Difunctor f => (b -> c) -> Context f a b -> Context f a c-cxtMap f (Hole x) = Hole (f x)-cxtMap _ (Var x) = Var x-cxtMap f (In t) = In (dimap id (cxtMap f) t)---- Param Functor--{-| Monads for which embedded @Trm@ values, which are parametric at top level,- can be made into monadic @Term@ values, i.e. \"pushing the parametricity- inwards\". -}-class ParamFunctor m where- termM :: (forall a. m (Trm f a)) -> m (Term f)--coerceTermM :: ParamFunctor m => (forall a. m (Trm f a)) -> m (Term f)-{-# INLINE coerceTermM #-}-coerceTermM t = unsafeCoerce t--{-# RULES- "termM/coerce" termM = coerceTermM- #-}--instance ParamFunctor Maybe where- termM Nothing = Nothing- termM x = Just (Term $ fromJust x)--instance ParamFunctor (Either a) where- termM (Left x) = Left x- termM x = Right (Term $ fromRight x)- where fromRight :: Either a b -> b- fromRight (Right x) = x- fromRight _ = error "fromRight: Left"--instance ParamFunctor [] where- termM [] = []- termM l = Term (head l) : termM (tail l)
− src/Data/Comp/Param/Thunk.hs
@@ -1,127 +0,0 @@-{-# LANGUAGE TypeOperators, FlexibleContexts, Rank2Types, GADTs #-}------------------------------------------------------------------------------------- |--- Module : Data.Comp.Param.Thunk--- Copyright : (c) 2011 Patrick Bahr--- License : BSD3--- Maintainer : Patrick Bahr <paba@diku.dk>--- Stability : experimental--- Portability : non-portable (GHC Extensions)------ This modules defines terms & contexts with thunks, with deferred--- monadic computations.--------------------------------------------------------------------------------------module Data.Comp.Param.Thunk- (TermT- ,TrmT- ,CxtT- ,Thunk- ,thunk- ,whnf- ,whnf'- ,whnfPr- ,nf- ,nfT- ,nfPr- ,nfTPr- ,evalStrict- ,AlgT- ,strict- ,strict')- where--import Data.Comp.Param.Term-import Data.Comp.Param.Sum-import Data.Comp.Param.Ops-import Data.Comp.Param.Algebra-import Data.Comp.Param.Ditraversable-import Data.Comp.Param.Difunctor--import Control.Monad---- | This type represents terms with thunks.-type TermT m f = Term (Thunk m :+: f)---- | This type represents terms with thunks.-type TrmT m f a = Trm (Thunk m :+: f) a---- | This type represents contexts with thunks.-type CxtT h m f a = Cxt h (Thunk m :+: f) a--newtype Thunk m a b = Thunk (m b)---- | This function turns a monadic computation into a thunk.-thunk :: (Thunk m :<: f) => m (Cxt h f a b) -> Cxt h f a b-thunk = inject . Thunk---- | This function evaluates all thunks until a non-thunk node is--- found.-whnf :: Monad m => TrmT m f a -> m (Either a (f a (TrmT m f a)))-whnf (In (Inl (Thunk m))) = m >>= whnf-whnf (In (Inr t)) = return $ Right t-whnf (Var x) = return $ Left x--whnf' :: Monad m => TrmT m f a -> m (TrmT m f a)-whnf' = liftM (either Var inject) . whnf---- | This function first evaluates the argument term into whnf via--- 'whnf' and then projects the top-level signature to the desired--- subsignature. Failure to do the projection is signalled as a--- failure in the monad.-whnfPr :: (Monad m, g :<: f) => TrmT m f a -> m (g a (TrmT m f a))-whnfPr t = do res <- whnf t- case res of- Left _ -> fail "cannot project variable"- Right t ->- case proj t of- Just res' -> return res'- Nothing -> fail "projection failed"----- | This function evaluates all thunks.-nfT :: (ParamFunctor m, Monad m, Ditraversable f) => TermT m f -> m (Term f)-nfT t = termM $ nf $ unTerm t---- | This function evaluates all thunks.-nf :: (Monad m, Ditraversable f) => TrmT m f a -> m (Trm f a)-nf = either (return . Var) (liftM In . dimapM nf) <=< whnf---- | This function evaluates all thunks while simultaneously--- projecting the term to a smaller signature. Failure to do the--- projection is signalled as a failure in the monad as in 'whnfPr'.-nfTPr :: (ParamFunctor m, Monad m, Ditraversable g, g :<: f) => TermT m f -> m (Term g)-nfTPr t = termM $ nfPr $ unTerm t---- | This function evaluates all thunks while simultaneously--- projecting the term to a smaller signature. Failure to do the--- projection is signalled as a failure in the monad as in 'whnfPr'.-nfPr :: (Monad m, Ditraversable g, g :<: f) => TrmT m f a -> m (Trm g a)-nfPr = liftM In . dimapM nfPr <=< whnfPr---evalStrict :: (Ditraversable g, Monad m, g :<: f) => - (g (TrmT m f a) (f a (TrmT m f a)) -> TrmT m f a)- -> g (TrmT m f a) (TrmT m f a) -> TrmT m f a-evalStrict cont t = thunk $ do - t' <- dimapM (liftM (either (const Nothing) Just) . whnf) t- case disequence t' of- Nothing -> return $ inject' t- Just s -> return $ cont s- ---- | This type represents algebras which have terms with thunks as--- carrier.-type AlgT m f g = Alg f (TermT m g)---- | This combinator makes the evaluation of the given functor--- application strict by evaluating all thunks of immediate subterms.-strict :: (f :<: g, Ditraversable f, Monad m) => f a (TrmT m g a) -> TrmT m g a-strict x = thunk $ liftM inject $ dimapM whnf' x---- | This combinator makes the evaluation of the given functor--- application strict by evaluating all thunks of immediate subterms.-strict' :: (f :<: g, Ditraversable f, Monad m) => f (TrmT m g a) (TrmT m g a) -> TrmT m g a-strict' = strict . dimap Var id
+ src/Data/Comp/Projection.hs view
@@ -0,0 +1,76 @@+{-# LANGUAGE ConstraintKinds #-}+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE KindSignatures #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE TypeOperators #-}+{-# LANGUAGE UndecidableInstances #-}++++--------------------------------------------------------------------------------+-- |+-- Module : Data.Comp.Projection+-- Copyright : (c) 2014 Patrick Bahr+-- License : BSD3+-- Maintainer : Patrick Bahr <paba@di.ku.dk>+-- Stability : experimental+-- Portability : non-portable (GHC Extensions)+--+-- This module provides a generic projection function 'pr' for+-- arbitrary nested binary products.+--+--------------------------------------------------------------------------------+++module Data.Comp.Projection (pr, (:<)) where++import Data.Comp.SubsumeCommon++import Data.Kind++type family Elem (f :: Type)+ (g :: Type) :: Emb where+ Elem f f = Found Here+ Elem (f1, f2) g = Sum' (Elem f1 g) (Elem f2 g)+ Elem f (g1, g2) = Choose (Elem f g1) (Elem f g2)+ Elem f g = NotFound++class Proj (e :: Emb) (p :: Type)+ (q :: Type) where+ pr' :: Proxy e -> q -> p++instance Proj (Found Here) f f where+ pr' _ = id++instance Proj (Found p) f g => Proj (Found (Le p)) f (g, g') where+ pr' _ = pr' (P :: Proxy (Found p)) . fst+++instance Proj (Found p) f g => Proj (Found (Ri p)) f (g', g) where+ pr' _ = pr' (P :: Proxy (Found p)) . snd+++instance (Proj (Found p1) f1 g, Proj (Found p2) f2 g)+ => Proj (Found (Sum p1 p2)) (f1, f2) g where+ pr' _ x = (pr' (P :: Proxy (Found p1)) x, pr' (P :: Proxy (Found p2)) x)+++infixl 5 :<++-- | The constraint @e :< p@ expresses that @e@ is a component of the+-- type @p@. That is, @p@ is formed by binary products using the type+-- @e@. The occurrence of @e@ must be unique. For example we have @Int+-- :< (Bool,(Int,Bool))@ but not @Bool :< (Bool,(Int,Bool))@.++type f :< g = (Proj (ComprEmb (Elem f g)) f g)+++-- | This function projects the component of type @e@ out or the+-- compound value of type @p@.++pr :: forall p q . (p :< q) => q -> p+pr = pr' (P :: Proxy (ComprEmb (Elem p q)))
+ src/Data/Comp/Render.hs view
@@ -0,0 +1,36 @@+{-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE TypeSynonymInstances #-}+module Data.Comp.Render where++import Data.Comp+import Data.Comp.Derive+import Data.Comp.Show ()+import Data.Foldable (toList)+import Data.Tree (Tree (..))+import Data.Tree.View++-- | The 'stringTree' algebra of a functor. The default instance creates a tree+-- with the same structure as the term.+class (Functor f, Foldable f, ShowConstr f) => Render f where+ stringTreeAlg :: Alg f (Tree String)+ stringTreeAlg f = Node (showConstr f) $ toList f++-- | Convert a term to a 'Tree'+stringTree :: Render f => Term f -> Tree String+stringTree = cata stringTreeAlg++-- | Show a term using ASCII art+showTerm :: Render f => Term f -> String+showTerm = showTree . stringTree++-- | Print a term using ASCII art+drawTerm :: Render f => Term f -> IO ()+drawTerm = putStrLn . showTerm++-- | Write a term to an HTML file with foldable nodes+writeHtmlTerm :: Render f => FilePath -> Term f -> IO ()+writeHtmlTerm file+ = writeHtmlTree Nothing file+ . fmap (\n -> NodeInfo InitiallyExpanded n "") . stringTree++$(derive [liftSum] [''Render])
src/Data/Comp/Show.hs view
@@ -1,4 +1,7 @@-{-# LANGUAGE TypeOperators, GADTs, TemplateHaskell, TypeSynonymInstances #-}+{-# LANGUAGE GADTs #-}+{-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE TypeOperators #-}+{-# LANGUAGE TypeSynonymInstances #-} -------------------------------------------------------------------------------- -- | -- Module : Data.Comp.Show@@ -17,12 +20,12 @@ ( ShowF(..) ) where -import Data.Comp.Term-import Data.Comp.Annotation import Data.Comp.Algebra+import Data.Comp.Annotation import Data.Comp.Derive (liftSum)-import Data.Comp.Derive.Utils (derive) import Data.Comp.Derive.Show+import Data.Comp.Derive.Utils (derive)+import Data.Comp.Term instance (Functor f, ShowF f) => ShowF (Cxt h f) where showF (Hole s) = s@@ -36,3 +39,8 @@ $(derive [liftSum] [''ShowF]) $(derive [makeShowF] [''Maybe, ''[], ''(,)])++instance (ShowConstr f, Show p) => ShowConstr (f :&: p) where+ showConstr (v :&: p) = showConstr v ++ " :&: " ++ show p++$(derive [liftSum] [''ShowConstr])
+ src/Data/Comp/SubsumeCommon.hs view
@@ -0,0 +1,168 @@+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE TypeOperators #-}+{-# LANGUAGE UndecidableInstances #-}+{-# LANGUAGE PolyKinds #-}++--------------------------------------------------------------------------------+-- |+-- Module : Data.Comp.SubsumeCommon+-- Copyright : (c) 2014 Patrick Bahr+-- License : BSD3+-- Maintainer : Patrick Bahr <paba@diku.dk>+-- Stability : experimental+-- Portability : non-portable (GHC Extensions)+--+-- Shared parts of the implementation of signature subsumption for+-- both the base and the multi library.+--+--------------------------------------------------------------------------------++module Data.Comp.SubsumeCommon+ ( ComprEmb+ , Pos (..)+ , Emb (..)+ , Choose+ , Sum'+ , Proxy (..)+ ) where++-- | This type is used in its promoted form only. It represents+-- pointers from the left-hand side of a subsumption to the right-hand+-- side.+data Pos = Here | Le Pos | Ri Pos | Sum Pos Pos++-- | This type is used in its promoted form only. It represents+-- possible results for checking for subsumptions. 'Found' indicates a+-- subsumption was found; 'NotFound' indicates no such subsumption was+-- found. 'Ambiguous' indicates that there are duplicates on the left-+-- or the right-hand side.+data Emb = Found Pos | NotFound | Ambiguous++data Proxy a = P+++type family Choose (e1 :: Emb) (r :: Emb) :: Emb where+ Choose (Found x) (Found y) = Ambiguous+ Choose Ambiguous y = Ambiguous+ Choose x Ambiguous = Ambiguous+ Choose (Found x) y = Found (Le x)+ Choose x (Found y) = Found (Ri y)+ Choose x y = NotFound+++type family Sum' (e1 :: Emb) (r :: Emb) :: Emb where+ Sum' (Found x) (Found y) = Found (Sum x y)+ Sum' Ambiguous y = Ambiguous+ Sum' x Ambiguous = Ambiguous+ Sum' NotFound y = NotFound+ Sum' x NotFound = NotFound+++-- | This type family takes a position type and compresses it. That+-- means it replaces each nested occurrence of+--+-- @+-- Sum (prefix (Le Here)) (prefix (Ri Here))@+-- @+---+-- with+--+-- @+-- prefix Here@+-- @+--+-- where @prefix@ is some composition of @Le@ and @Ri@. The rational+-- behind this type family is that it provides a more compact proof+-- term of a subsumption, and thus yields more efficient+-- implementations of 'inj' and 'prj'.++type family ComprPos (p :: Pos) :: Pos where+ ComprPos Here = Here+ ComprPos (Le p) = Le (ComprPos p)+ ComprPos (Ri p) = Ri (ComprPos p)+ ComprPos (Sum l r) = CombineRec (ComprPos l) (ComprPos r)+++-- | Helper type family for 'ComprPos'. Note that we could have+-- defined this as a type synonym. But if we do that, performance+-- becomes abysmal. I presume that the reason for this huge impact on+-- performance lies in the fact that right-hand side of the defining+-- equation duplicates the two arguments @l@ and @r@.+type family CombineRec l r where+ CombineRec l r = CombineMaybe (Sum l r) (Combine l r)++-- | Helper type family for 'ComprPos'.+type family CombineMaybe (p :: Pos) (p' :: Maybe Pos) where+ CombineMaybe p (Just p') = p'+ CombineMaybe p p' = p+++-- | Helper type family for 'ComprPos'.+type family Combine (l :: Pos) (r :: Pos) :: Maybe Pos where+ Combine (Le l) (Le r) = Le' (Combine l r)+ Combine (Ri l) (Ri r) = Ri' (Combine l r)+ Combine (Le Here) (Ri Here) = Just Here+ Combine l r = Nothing++-- | 'Ri' lifted to 'Maybe'.+type family Ri' (p :: Maybe Pos) :: Maybe Pos where+ Ri' Nothing = Nothing+ Ri' (Just p) = Just (Ri p)++-- | 'Le' lifted to 'Maybe'.+type family Le' (p :: Maybe Pos) :: Maybe Pos where+ Le' Nothing = Nothing+ Le' (Just p) = Just (Le p)+++-- | If the argument is not 'Found', this type family is the+-- identity. Otherwise, the argument is of the form @Found p@, and+-- this type family does two things: (1) it checks whether @p@ the+-- contains duplicates; and (2) it compresses @p@ using 'ComprPos'. If+-- (1) finds no duplicates, @Found (ComprPos p)@ is returned;+-- otherwise @Ambiguous@ is returned.+--+-- For (1) it is assumed that @p@ does not contain 'Sum' nested+-- underneath a 'Le' or 'Ri' (i.e. only at the root or underneath a+-- 'Sum'). We will refer to such positions below as /atomic position/.+-- Positions not containing 'Sum' are called /simple positions/.+type family ComprEmb (e :: Emb) :: Emb where+ ComprEmb (Found p) = Check (Dupl p) (ComprPos p)+ ComprEmb e = e++-- | Helper type family for 'ComprEmb'.+type family Check (b :: Bool) (p :: Pos) where+ Check False p = Found p+ Check True p = Ambiguous++-- | This type family turns a list of /atomic position/ into a list of+-- /simple positions/ by recursively splitting each position of the+-- form @Sum p1 p2@ into @p1@ and @p2@.+type family ToList (s :: [Pos]) :: [Pos] where+ ToList (Sum p1 p2 ': s) = ToList (p1 ': p2 ': s)+ ToList (p ': s) = p ': ToList s+ ToList '[] = '[]++-- | This type checks whether the argument (atomic) position has+-- duplicates.+type Dupl s = Dupl' (ToList '[s])++-- | This type family checks whether the list of positions given as an+-- argument contains any duplicates.+type family Dupl' (s :: [Pos]) :: Bool where+ Dupl' (p ': r) = OrDupl' (Find p r) r+ Dupl' '[] = False++-- | This type family checks whether its first argument is contained+-- its second argument.+type family Find (p :: Pos) (s :: [Pos]) :: Bool where+ Find p (p ': r) = True+ Find p (p' ': r) = Find p r+ Find p '[] = False++-- | This type family returns @True@ if the first argument is true;+-- otherwise it checks the second argument for duplicates.+type family OrDupl' (a :: Bool) (b :: [Pos]) :: Bool where+ OrDupl' True c = True+ OrDupl' False c = Dupl' c
src/Data/Comp/Sum.hs view
@@ -1,6 +1,12 @@-{-# LANGUAGE TypeOperators, MultiParamTypeClasses, IncoherentInstances,- FlexibleInstances, FlexibleContexts, GADTs, TypeSynonymInstances,- ScopedTypeVariables, TemplateHaskell #-}+{-# LANGUAGE ConstraintKinds #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE GADTs #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE Rank2Types #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeOperators #-}+{-# LANGUAGE TypeSynonymInstances #-} -------------------------------------------------------------------------------- -- | -- Module : Data.Comp.Sum@@ -17,77 +23,28 @@ module Data.Comp.Sum ( (:<:),+ (:=:), (:+:), caseF, -- * Projections for Signatures and Terms proj,- proj2,- proj3,- proj4,- proj5,- proj6,- proj7,- proj8,- proj9,- proj10, project,- project2,- project3,- project4,- project5,- project6,- project7,- project8,- project9,- project10, deepProject,- deepProject2,- deepProject3,- deepProject4,- deepProject5,- deepProject6,- deepProject7,- deepProject8,- deepProject9,- deepProject10,+ project_,+ deepProject_, -- * Injections for Signatures and Terms inj,- inj2,- inj3,- inj4,- inj5,- inj6,- inj7,- inj8,- inj9,- inj10, inject,- inject2,- inject3,- inject4,- inject5,- inject6,- inject7,- inject8,- inject9,- inject10, deepInject,- deepInject2,- deepInject3,- deepInject4,- deepInject5,- deepInject6,- deepInject7,- deepInject8,- deepInject9,- deepInject10,+ inject_,+ deepInject_, + split,+ -- * Injections and Projections for Constants injectConst,- injectConst2,- injectConst3, projectConst, injectCxt, liftCxt,@@ -95,31 +52,30 @@ substHoles' ) where -import Data.Comp.Term import Data.Comp.Algebra import Data.Comp.Ops-import Data.Comp.Derive.Projections-import Data.Comp.Derive.Injections+import Data.Comp.Term -import Control.Monad hiding (mapM,sequence)-import Prelude hiding (mapM,sequence)+import Control.Monad hiding (mapM, sequence)+import Prelude hiding (mapM, sequence) -import Data.Maybe-import Data.Traversable import Data.Map (Map) import qualified Data.Map as Map+import Data.Maybe -$(liftM concat $ mapM projn [2..10])- -- |Project the outermost layer of a term to a sub signature. If the signature -- @g@ is compound of /n/ atomic signatures, use @project@/n/ instead. project :: (g :<: f) => Cxt h f a -> Maybe (g (Cxt h f a))-project (Hole _) = Nothing-project (Term t) = proj t+project = project_ proj -$(liftM concat $ mapM projectn [2..10])+-- |Project the outermost layer of a term to a sub signature. If the signature+-- @g@ is compound of /n/ atomic signatures, use @project@/n/ instead.+project_ :: SigFunM Maybe f g -> Cxt h f a -> Maybe (g (Cxt h f a))+project_ _ (Hole _) = Nothing+project_ f (Term t) = f t + -- | Tries to coerce a term/context to a term/context over a sub-signature. If -- the signature @g@ is compound of /n/ atomic signatures, use -- @deepProject@/n/ instead.@@ -127,55 +83,47 @@ {-# INLINE deepProject #-} deepProject = appSigFunM' proj -$(liftM concat $ mapM deepProjectn [2..10])-{-# INLINE deepProject2 #-}-{-# INLINE deepProject3 #-}-{-# INLINE deepProject4 #-}-{-# INLINE deepProject5 #-}-{-# INLINE deepProject6 #-}-{-# INLINE deepProject7 #-}-{-# INLINE deepProject8 #-}-{-# INLINE deepProject9 #-}-{-# INLINE deepProject10 #-}+-- | Tries to coerce a term/context to a term/context over a sub-signature. If+-- the signature @g@ is compound of /n/ atomic signatures, use+-- @deepProject@/n/ instead.+deepProject_ :: (Traversable g) => (SigFunM Maybe f g) -> CxtFunM Maybe f g+{-# INLINE deepProject_ #-}+deepProject_ = appSigFunM' -$(liftM concat $ mapM injn [2..10]) -- |Inject a term where the outermost layer is a sub signature. If the signature -- @g@ is compound of /n/ atomic signatures, use @inject@/n/ instead. inject :: (g :<: f) => g (Cxt h f a) -> Cxt h f a-inject = Term . inj+inject = inject_ inj -$(liftM concat $ mapM injectn [2..10])+-- |Inject a term where the outermost layer is a sub signature. If the signature+-- @g@ is compound of /n/ atomic signatures, use @inject@/n/ instead.+inject_ :: SigFun g f -> g (Cxt h f a) -> Cxt h f a+inject_ f = Term . f + -- |Inject a term over a sub signature to a term over larger signature. If the -- signature @g@ is compound of /n/ atomic signatures, use @deepInject@/n/ -- instead. deepInject :: (Functor g, g :<: f) => CxtFun g f {-# INLINE deepInject #-}-deepInject = appSigFun inj+deepInject = deepInject_ inj -$(liftM concat $ mapM deepInjectn [2..10])-{-# INLINE deepInject2 #-}-{-# INLINE deepInject3 #-}-{-# INLINE deepInject4 #-}-{-# INLINE deepInject5 #-}-{-# INLINE deepInject6 #-}-{-# INLINE deepInject7 #-}-{-# INLINE deepInject8 #-}-{-# INLINE deepInject9 #-}-{-# INLINE deepInject10 #-}+-- |Inject a term over a sub signature to a term over larger signature. If the+-- signature @g@ is compound of /n/ atomic signatures, use @deepInject@/n/+-- instead.+deepInject_ :: (Functor g) => SigFun g f -> CxtFun g f+{-# INLINE deepInject_ #-}+deepInject_ = appSigFun ++split :: (f :=: f1 :+: f2) => (f1 (Term f) -> a) -> (f2 (Term f) -> a) -> Term f -> a+split f1 f2 (Term t) = spl f1 f2 t+ injectConst :: (Functor g, g :<: f) => Const g -> Cxt h f a injectConst = inject . fmap (const undefined) -injectConst2 :: (Functor f1, Functor f2, Functor g, f1 :<: g, f2 :<: g)- => Const (f1 :+: f2) -> Cxt h g a-injectConst2 = inject2 . fmap (const undefined) -injectConst3 :: (Functor f1, Functor f2, Functor f3, Functor g, f1 :<: g, f2 :<: g, f3 :<: g)- => Const (f1 :+: f2 :+: f3) -> Cxt h g a-injectConst3 = inject3 . fmap (const undefined)- projectConst :: (Functor g, g :<: f) => Cxt h f a -> Maybe (Const g) projectConst = fmap (fmap (const ())) . project @@ -197,11 +145,7 @@ substHoles' :: (Functor f, Functor g, f :<: g, Ord v) => Cxt h' f v -> Map v (Cxt h g a) -> Cxt h g a substHoles' c m = substHoles c (fromJust . (`Map.lookup` m)) -instance (Functor f) => Monad (Context f) where- return = Hole- (>>=) = substHoles - instance (Show (f a), Show (g a)) => Show ((f :+: g) a) where show (Inl v) = show v show (Inr v) = show v@@ -216,5 +160,5 @@ instance (Eq (f a), Eq (g a)) => Eq ((f :+: g) a) where (Inl x) == (Inl y) = x == y- (Inr x) == (Inr y) = x == y + (Inr x) == (Inr y) = x == y _ == _ = False
src/Data/Comp/Term.hs view
@@ -1,4 +1,9 @@-{-# LANGUAGE EmptyDataDecls, GADTs, KindSignatures, Rank2Types #-}+{-# LANGUAGE EmptyDataDecls #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE GADTs #-}+{-# LANGUAGE KindSignatures #-}+{-# LANGUAGE Rank2Types #-}+{-# LANGUAGE TypeSynonymInstances #-} -------------------------------------------------------------------------------- -- | -- Module : Data.Comp.Term@@ -30,11 +35,12 @@ import Control.Applicative hiding (Const) import Control.Monad hiding (mapM, sequence) -import Data.Traversable+import Data.Kind import Data.Foldable+import Data.Traversable import Unsafe.Coerce -import Prelude hiding (mapM, sequence, foldl, foldl1, foldr, foldr1)+import Prelude hiding (foldl, foldl1, foldr, foldr1, mapM, sequence) {-| -}@@ -53,7 +59,7 @@ second parameter is the signature of the context. The third parameter is the type of the holes. -} -data Cxt :: * -> (* -> *) -> * -> * where+data Cxt :: Type -> (Type -> Type) -> Type -> Type where Term :: f (Cxt h f a) -> Cxt h f a Hole :: a -> Cxt Hole f a @@ -94,6 +100,15 @@ where run (Hole v) = Hole (f v) run (Term t) = Term (fmap run t) +instance Functor f => Applicative (Context f) where+ pure = Hole+ (<*>) = ap++instance (Functor f) => Monad (Context f) where+ m >>= f = run m+ where run (Hole v) = f v+ run (Term t) = Term (fmap run t)+ instance (Foldable f) => Foldable (Cxt h f) where foldr op c a = run a c where run (Hole a) e = a `op` e@@ -114,11 +129,11 @@ traverse f = run where run (Hole a) = Hole <$> f a run (Term t) = Term <$> traverse run t- + sequenceA (Hole a) = Hole <$> a sequenceA (Term t) = Term <$> traverse sequenceA t - mapM f = run + mapM f = run where run (Hole a) = liftM Hole $ f a run (Term t) = liftM Term $ mapM run t
src/Data/Comp/TermRewriting.hs view
@@ -1,4 +1,5 @@-{-# LANGUAGE Rank2Types, GADTs #-}+{-# LANGUAGE GADTs #-}+{-# LANGUAGE Rank2Types #-} -------------------------------------------------------------------------------- -- | -- Module : Data.Comp.TermRewriting@@ -17,16 +18,16 @@ import Prelude hiding (any) -import Data.Comp.Term-import Data.Comp.Sum import Data.Comp.Algebra import Data.Comp.Equality import Data.Comp.Matching+import Data.Comp.Sum+import Data.Comp.Term+import Data.Foldable import Data.Map (Map) import qualified Data.Map as Map-import qualified Data.Set as Set import Data.Maybe-import Data.Foldable+import qualified Data.Set as Set import Control.Monad @@ -84,7 +85,7 @@ appRule :: (Ord v, EqF f, Eq a, Functor f, Foldable f) => Rule f f v -> Step (Cxt h f a)-appRule rule t = do +appRule rule t = do (res, subst) <- matchRule rule t return $ substHoles' res subst @@ -134,10 +135,10 @@ parallelStep _ Hole{} = Nothing parallelStep trs c@(Term t) = case matchRules trs c of- Nothing + Nothing | anyBelow -> Just $ Term $ fmap fst below | otherwise -> Nothing- where below = fmap (bStep $ parallelStep trs) t + where below = fmap (bStep $ parallelStep trs) t anyBelow = any snd below Just (rhs,subst) -> Just $ substHoles' rhs substBelow where rhsVars = Set.fromList $ toList rhs@@ -145,7 +146,7 @@ apply v t | Set.member v rhsVars = Just $ fst $ bStep (parallelStep trs) t | otherwise = Nothing- + {-| This function applies the given reduction step repeatedly until a normal form is reached. -}
src/Data/Comp/Thunk.hs view
@@ -1,4 +1,9 @@-{-# LANGUAGE TypeOperators, FlexibleContexts, Rank2Types, ScopedTypeVariables #-}+{-# LANGUAGE ConstraintKinds #-}+{-# LANGUAGE CPP #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE Rank2Types #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeOperators #-} -------------------------------------------------------------------------------- -- |@@ -36,20 +41,20 @@ ,strict ,strictAt) where -import Data.Comp.Term-import Data.Comp.Equality import Data.Comp.Algebra-import Data.Comp.Ops+import Data.Comp.Equality+import Data.Comp.Mapping+import Data.Comp.Ops ((:+:) (..), fromInr) import Data.Comp.Sum-import Data.Comp.Number+import Data.Comp.Term import Data.Foldable hiding (and) -import qualified Data.Set as Set+import qualified Data.IntSet as IntSet +import Control.Monad hiding (mapM, sequence) import Data.Traversable-import Control.Monad hiding (sequence,mapM) -import Prelude hiding (foldr, foldl,foldr1, foldl1,sequence,mapM)+import Prelude hiding (foldl, foldl1, foldr, foldr1, mapM, sequence) -- | This type represents terms with thunks.@@ -60,8 +65,8 @@ -- | This function turns a monadic computation into a thunk.-thunk :: (m :<: f) => m (Cxt h f a) -> Cxt h f a-thunk = inject+thunk :: m (CxtT m h f a) -> CxtT m h f a+thunk = inject_ Inl -- | This function evaluates all thunks until a non-thunk node is -- found.@@ -70,13 +75,13 @@ whnf (Term (Inr t)) = return t whnf' :: Monad m => TermT m f -> m (TermT m f)-whnf' = liftM inject . whnf+whnf' = liftM (inject_ Inr) . whnf -- | This function first evaluates the argument term into whnf via -- 'whnf' and then projects the top-level signature to the desired -- subsignature. Failure to do the projection is signalled as a -- failure in the monad.-whnfPr :: (Monad m, g :<: f) => TermT m f -> m (g (TermT m f))+whnfPr :: (MonadFail m, g :<: f) => TermT m f -> m (g (TermT m f)) whnfPr t = do res <- whnf t case proj res of Just res' -> return res'@@ -98,7 +103,7 @@ -- (using 'whnf') according to the given function. eval2 :: Monad m => (f (TermT m f) -> f (TermT m f) -> TermT m f) -> TermT m f -> TermT m f -> TermT m f-eval2 cont x y = (\ x' -> cont x' `eval` y) `eval` x +eval2 cont x y = (\ x' -> cont x' `eval` y) `eval` x -- | This function evaluates all thunks. nf :: (Monad m, Traversable f) => TermT m f -> m (Term f)@@ -107,16 +112,16 @@ -- | This function evaluates all thunks while simultaneously -- projecting the term to a smaller signature. Failure to do the -- projection is signalled as a failure in the monad as in 'whnfPr'.-nfPr :: (Monad m, Traversable g, g :<: f) => TermT m f -> m (Term g)+nfPr :: (MonadFail m, Traversable g, g :<: f) => TermT m f -> m (Term g) nfPr = liftM Term . mapM nfPr <=< whnfPr -- | This function inspects a term (using 'nf') according to the -- given function.-deepEval :: (Traversable f, Monad m) => +deepEval :: (Traversable f, Monad m) => (Term f -> TermT m f) -> TermT m f -> TermT m f-deepEval cont v = case deepProject v of +deepEval cont v = case deepProject_ fromInr v of Just v' -> cont v'- _ -> thunk $ liftM cont $ nf v + _ -> thunk $ liftM cont $ nf v infixl 1 #>> @@ -150,22 +155,22 @@ -- | This combinator makes the evaluation of the given functor -- application strict by evaluating all thunks of immediate subterms. strict :: (f :<: g, Traversable f, Monad m) => f (TermT m g) -> TermT m g-strict x = thunk $ liftM inject $ mapM whnf' x+strict x = thunk $ liftM (inject_ (Inr . inj)) $ mapM whnf' x -- | This type represents position representations for a functor -- @f@. It is a function that extracts a number of components (of -- polymorphic type @a@) from a functorial value and puts it into a -- list.-type Pos f = forall a . Ord a => f a -> [a]+type Pos f = forall a . f a -> [a] -- | This combinator is a variant of 'strict' that only makes a subset -- of the arguments of a functor application strict. The first -- argument of this combinator specifies which positions are supposed -- to be strict. strictAt :: (f :<: g, Traversable f, Monad m) => Pos f -> f (TermT m g) -> TermT m g-strictAt p s = thunk $ liftM inject $ mapM run s'+strictAt p s = thunk $ liftM (inject_ (Inr . inj)) $ mapM run s' where s' = number s- isStrict e = Set.member e $ Set.fromList $ p s'+ isStrict (Numbered i _) = IntSet.member i $ IntSet.fromList $ map (\(Numbered i _) -> i) $ p s' run e | isStrict e = whnf' $ unNumbered e | otherwise = return $ unNumbered e
src/Data/Comp/Unification.hs view
@@ -1,4 +1,5 @@-{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE MultiParamTypeClasses #-} ------------------------------------------------------------------------------- -- | -- Module : Data.Comp.Unification@@ -15,15 +16,14 @@ module Data.Comp.Unification where +import Data.Comp.Decompose import Data.Comp.Term import Data.Comp.Variables-import Data.Comp.Decompose -import Control.Monad.Error+import Control.Monad+import Control.Monad.Except import Control.Monad.State -import Data.Traversable- import qualified Data.Map as Map {-| This type represents equations between terms over a specific@@ -42,10 +42,6 @@ | HeadSymbolMismatch (Term f) (Term f) | UnifError String -instance Error (UnifError f v) where- strMsg = UnifError-- -- | This is used in order to signal a failed occurs check during -- unification. failedOccursCheck :: (MonadError (UnifError f v) m) => v -> Term f -> m a@@ -87,12 +83,12 @@ withNextEq :: Monad m => (Equation f -> UnifyM f v m ()) -> UnifyM f v m () withNextEq m = do eqs <- gets usEqs- case eqs of + case eqs of [] -> return () x : xs -> modify (\s -> s {usEqs = xs}) >> m x -putEqs :: Monad m +putEqs :: Monad m => Equations f -> UnifyM f v m () putEqs eqs = modify addEqs where addEqs s = s {usEqs = eqs ++ usEqs s}@@ -108,7 +104,7 @@ => UnifyM f v m () runUnify = withNextEq (\ e -> unifyStep e >> runUnify) -unifyStep :: (MonadError (UnifError f v) m, Decompose f v, Ord v, Eq (Const f), Traversable f) +unifyStep :: (MonadError (UnifError f v) m, Decompose f v, Ord v, Eq (Const f), Traversable f) => Equation f -> UnifyM f v m () unifyStep (s,t) = case decompose s of Var v1 -> case decompose t of
src/Data/Comp/Variables.hs view
@@ -1,5 +1,8 @@-{-# LANGUAGE MultiParamTypeClasses, GADTs, FlexibleInstances,- OverlappingInstances, TypeOperators, TemplateHaskell #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE GADTs #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE TypeOperators #-} -------------------------------------------------------------------------------- -- |@@ -29,20 +32,24 @@ substVars, appSubst, compSubst,- getBoundVars+ getBoundVars,+ (&),+ (|->),+ empty ) where -import Data.Comp.Term-import Data.Comp.Number import Data.Comp.Algebra import Data.Comp.Derive+import Data.Comp.Mapping+import Data.Comp.Term+import Data.Comp.Ops import Data.Foldable hiding (elem, notElem)+import Data.Map (Map)+import qualified Data.Map as Map import Data.Maybe import Data.Set (Set) import qualified Data.Set as Set-import Data.Map (Map)-import qualified Data.Map as Map-import Prelude hiding (or, foldl)+import Prelude hiding (foldl, or) -- | This type represents substitutions of contexts, i.e. finite -- mappings from variables to contexts.@@ -60,61 +67,69 @@ -- default implementation returns @Nothing@. isVar :: f a -> Maybe v isVar _ = Nothing- + -- | Indicates the set of variables bound by the @f@ constructor -- for each argument of the constructor. For example for a -- non-recursive let binding:+ -- -- @ -- data Let e = Let Var e e -- instance HasVars Let Var where- -- bindsVars (Let v x y) = Map.fromList [(y, (Set.singleton v))]+ -- bindsVars (Let v x y) = y |-> Set.singleton v -- @+ -- -- If, instead, the let binding is recursive, the methods has to -- be implemented like this:+ -- -- @- -- bindsVars (Let v x y) = Map.fromList [(x, (Set.singleton v)),- -- (y, (Set.singleton v))]+ -- bindsVars (Let v x y) = x |-> Set.singleton v &+ -- y |-> Set.singleton v -- @+ -- -- This indicates that the scope of the bound variable also -- extends to the right-hand side of the variable binding. -- -- The default implementation returns the empty map.- bindsVars :: Ord a => f a -> Map a (Set v)- bindsVars _ = Map.empty+ bindsVars :: Mapping m a => f a -> m (Set v)+ bindsVars _ = empty $(derive [liftSum] [''HasVars]) +instance HasVars f v => HasVars (f :&: a) v where+ isVar (f :&: _) = isVar f+ bindsVars (f :&: _) = bindsVars f+ -- | Same as 'isVar' but it returns Nothing@ instead of @Just v@ if -- @v@ is contained in the given set of variables.- + isVar' :: (HasVars f v, Ord v) => Set v -> f a -> Maybe v isVar' b t = do v <- isVar t if v `Set.member` b then Nothing else return v- + -- | This combinator pairs every argument of a given constructor with -- the set of (newly) bound variables according to the corresponding -- 'HasVars' type class instance. getBoundVars :: (HasVars f v, Traversable f) => f a -> f (Set v, a) getBoundVars t = let n = number t m = bindsVars n- trans x = (Map.findWithDefault Set.empty x m, unNumbered x)+ trans (Numbered i x) = (lookupNumMap Set.empty i m, x) in fmap trans n- + -- | This combinator combines 'getBoundVars' with the generic 'fmap' function. fmapBoundVars :: (HasVars f v, Traversable f) => (Set v -> a -> b) -> f a -> f b fmapBoundVars f t = let n = number t m = bindsVars n- trans x = f (Map.findWithDefault Set.empty x m) (unNumbered x)- in fmap trans n - --- | This combinator combines 'getBoundVars' with the generic 'foldl' function. + trans (Numbered i x) = f (lookupNumMap Set.empty i m) x+ in fmap trans n++-- | This combinator combines 'getBoundVars' with the generic 'foldl' function. foldlBoundVars :: (HasVars f v, Traversable f) => (b -> Set v -> a -> b) -> b -> f a -> b foldlBoundVars f e t = let n = number t m = bindsVars n- trans x y = f x (Map.findWithDefault Set.empty y m) (unNumbered y) + trans x (Numbered i y) = f x (lookupNumMap Set.empty i m) y in foldl trans e n -- | Convert variables to holes, except those that are bound.@@ -124,7 +139,7 @@ alg t vars = case isVar t of Just v | not (v `Set.member` vars) -> Hole v _ -> Term $ fmapBoundVars run t- where + where run newVars f = f $ newVars `Set.union` vars -- |Algebra for checking whether a variable is contained in a term, except those@@ -175,19 +190,19 @@ appSubst subst = substVars f where f v = Map.lookup v subst -instance (Ord v, HasVars f v, Traversable f)+instance {-# OVERLAPPABLE #-} (Ord v, HasVars f v, Traversable f) => SubstVars v (Cxt h f a) (Cxt h f a) where -- have to use explicit GADT pattern matching!! -- subst f = free (substAlg f) Hole substVars subst = doSubst Set.empty where doSubst _ (Hole a) = Hole a- doSubst b (Term t) = case isVar' b t >>= subst of + doSubst b (Term t) = case isVar' b t >>= subst of Just new -> new Nothing -> Term $ fmapBoundVars run t- where run vars s = doSubst (b `Set.union` vars) s+ where run vars = doSubst (b `Set.union` vars) -instance (SubstVars v t a, Functor f) => SubstVars v t (f a) where- substVars f = fmap (substVars f) +instance {-# OVERLAPPABLE #-} (SubstVars v t a, Functor f) => SubstVars v t (f a) where+ substVars f = fmap (substVars f) {-| This function composes two substitutions @s1@ and @s2@. That is, applying the resulting substitution is equivalent to first applying
testsuite/tests/Data/Comp/Equality_Test.hs view
@@ -2,13 +2,12 @@ import Data.Comp-import Data.Comp.Equality-import Data.Comp.Arbitrary-import Data.Comp.Show+import Data.Comp.Equality ()+import Data.Comp.Arbitrary ()+import Data.Comp.Show () import Test.Framework import Test.Framework.Providers.QuickCheck2-import Test.QuickCheck import Test.Utils @@ -34,4 +33,4 @@ Nothing -> False Just list -> all (uncurry (==)) $ map (\(x,y)->(f x,y)) list where cxt' = fmap f cxt - with = (cxt :: Context SigP Int, f :: Int -> Int)+ _with = (cxt :: Context SigP Int, f :: Int -> Int)
testsuite/tests/Data/Comp/Examples/Comp.hs view
@@ -11,10 +11,6 @@ import Test.Framework import Test.Framework.Providers.HUnit import Test.HUnit-import Test.Utils hiding (iPair)--- --------------------------------------------------------------------------------
testsuite/tests/Data/Comp/Examples/Multi.hs view
@@ -12,7 +12,6 @@ import Test.Framework import Test.Framework.Providers.HUnit import Test.HUnit-import Test.Utils hiding (iPair) -------------------------------------------------------------------------------- -- Test Suits
− testsuite/tests/Data/Comp/Examples/MultiParam.hs
@@ -1,34 +0,0 @@-{-# LANGUAGE TypeOperators #-}-module Data.Comp.Examples.MultiParam where--import Examples.MultiParam.FOL as FOL--import Data.Comp.MultiParam-import Data.Comp.MultiParam.FreshM (Name)--import Test.Framework-import Test.Framework.Providers.HUnit-import Test.HUnit-import Test.Utils----------------------------------------------------------------------------------------- Test Suits-----------------------------------------------------------------------------------tests = testGroup "Parametric Compositional Data Types" [- testCase "FOL" folTest- ]-------------------------------------------------------------------------------------- Properties-----------------------------------------------------------------------------------folTest = show (foodFact7 :: INF Name TFormula) @=? "(Person(x1) and Food(x2)) -> (Food(Skol2(x1)) or Person(Skol6(x2)))\n" ++- "(Person(x1) and Food(x2)) -> (Food(Skol2(x1)) or Eats(Skol6(x2), x2))\n" ++- "(Person(x1) and Eats(x1, Skol2(x1)) and Food(x2)) -> (Person(Skol6(x2)))\n" ++- "(Person(x1) and Eats(x1, Skol2(x1)) and Food(x2)) -> (Eats(Skol6(x2), x2))"
− testsuite/tests/Data/Comp/Examples/Param.hs
@@ -1,38 +0,0 @@-{-# LANGUAGE TypeOperators #-}-module Data.Comp.Examples.Param where--import Examples.Param.Names as Names-import Examples.Param.Graph as Graph--import Data.Comp.Param--import Test.Framework-import Test.Framework.Providers.HUnit-import Test.HUnit-import Test.Utils----------------------------------------------------------------------------------------- Test Suits-----------------------------------------------------------------------------------tests = testGroup "Parametric Compositional Data Types" [- testCase "names" namesTest,- testCase "graph" graphTest- ]-------------------------------------------------------------------------------------- Properties-----------------------------------------------------------------------------------instance (EqD f, PEq p) => EqD (f :&: p) where- eqD (v1 :&: p1) (v2 :&: p2) = do b1 <- peq p1 p2- b2 <- eqD v1 v2- return $ b1 && b2--namesTest = sequence_ [en @=? en', ep @=? ep']-graphTest = sequence_ [n @=? 5, f @=? [0,2,1,2]]
testsuite/tests/Data/Comp/Examples_Test.hs view
@@ -3,17 +3,10 @@ import qualified Data.Comp.Examples.Comp as C import qualified Data.Comp.Examples.Multi as M-import qualified Data.Comp.Examples.Param as P-import qualified Data.Comp.Examples.MultiParam as MP import Test.Framework-import Test.Framework.Providers.QuickCheck2-import Test.QuickCheck-import Test.Utils tests = testGroup "Examples" [ C.tests,- M.tests,- P.tests,- MP.tests+ M.tests ]
testsuite/tests/Data/Comp/Multi/Variables_Test.hs view
@@ -1,6 +1,6 @@ {-# LANGUAGE TemplateHaskell, TypeSynonymInstances, FlexibleInstances, MultiParamTypeClasses, TypeOperators, FlexibleContexts , RankNTypes,-GADTs, ScopedTypeVariables, EmptyDataDecls#-}+GADTs, ScopedTypeVariables, EmptyDataDecls, ConstraintKinds #-} module Data.Comp.Multi.Variables_Test where @@ -64,16 +64,16 @@ isVar (Var v) = Just v isVar _ = Nothing - bindsVars (Abs v a) = Map.singleton (E a) (Set.singleton v)- bindsVars _ = Map.empty+ bindsVars (Abs v a) = a |-> Set.singleton v+ bindsVars _ = empty instance HasVars Op a where instance HasVars Let Var where- bindsVars (Let v _ a) = Map.singleton (E a) (Set.singleton v)+ bindsVars (Let v _ a) = a |-> Set.singleton v instance HasVars LetRec Var where- bindsVars (LetRec v a b) = Map.fromList [(E a,vs),(E b,vs)]+ bindsVars (LetRec v a b) = a |-> vs & b |-> vs where vs = Set.singleton v -- let x = x + 1 in (\y. y + x) z
+ testsuite/tests/Data/Comp/Subsume_Test.hs view
@@ -0,0 +1,56 @@+{-# LANGUAGE TypeOperators, DataKinds, TypeFamilies #-}++-- | This module exports a dummy test to force type checking of this+-- module. In this module we test the subtyping system.++module Data.Comp.Subsume_Test where++import Data.Comp+import Data.Comp.Ops+import Data.Comp.SubsumeCommon+++import Test.Framework+import Test.Framework.Providers.QuickCheck2+++data S1 a = S1 a+data S2 a = S2 a+data S3 a = S3 a+data S4 a = S4 a++type TA = S1 :+: S2+type TB = S3 :+: S4+type T1 = TA :+: TB+type T2 = TB :+: TA+type T3 = S2 :+: TB++test1 :: ComprEmb (Elem T1 T1) ~ (Found Here) => Int+test1 = 1++test2 :: ComprEmb (Elem T1 T2) ~ (Found (Sum (Ri Here) (Le Here))) => Int+test2 = 1++test3 :: ComprEmb (Elem (T1 :+: S1) T2) ~ Ambiguous => Int+test3 = 1++test4 :: ComprEmb (Elem T1 (T2 :+: S1)) ~ Ambiguous => Int+test4 = 1++test5 :: ComprEmb (Elem T1 T3) ~ NotFound => Int+test5 = 1++test6 :: ComprEmb (Elem TB T1) ~ (Found (Ri Here)) => Int+test6 = 1++test7 :: ComprEmb (Elem T3 T1) ~ (Found (Sum (Le (Ri Here))(Ri Here))) => Int+test7 = 1++main = defaultMain [tests]++tests = testGroup "Subsume" [+ testProperty "prop_typecheck" prop_typecheck+ ]++-- dummy test+prop_typecheck = True
testsuite/tests/Data/Comp/Variables_Test.hs view
@@ -1,5 +1,6 @@-{-# LANGUAGE TemplateHaskell, TypeSynonymInstances,-FlexibleInstances, MultiParamTypeClasses, TypeOperators, FlexibleContexts#-}+{-# LANGUAGE TemplateHaskell, TypeSynonymInstances, FlexibleInstances, MultiParamTypeClasses, + TypeOperators, FlexibleContexts, ConstraintKinds #-}+{-# LANGUAGE DeriveFunctor #-} module Data.Comp.Variables_Test where @@ -10,9 +11,7 @@ import Data.Comp.Term import Data.Comp.Show () -import Data.Map (Map) import qualified Data.Map as Map-import Data.Set (Set) import qualified Data.Set as Set import Test.Framework@@ -31,13 +30,17 @@ data Val e = Abs Var e | Var Var | Int Int+ deriving Functor data Op e = App e e | Plus e e+ deriving Functor data Let e = Let Var e e+ deriving Functor data LetRec e = LetRec Var e e+ deriving Functor type Sig = Op :+: Val @@ -45,7 +48,7 @@ type SigRec = LetRec :+: Sig -$(derive [makeFunctor, makeTraversable, makeFoldable,+$(derive [makeTraversable, makeFoldable, makeEqF, makeShowF, smartConstructors] [''Op, ''Val, ''Let, ''LetRec]) @@ -53,16 +56,16 @@ isVar (Var v) = Just v isVar _ = Nothing - bindsVars (Abs v a) = Map.singleton a (Set.singleton v)- bindsVars _ = Map.empty+ bindsVars (Abs v a) = a |-> Set.singleton v+ bindsVars _ = empty instance HasVars Op a where instance HasVars Let Var where- bindsVars (Let v _ a) = Map.singleton a (Set.singleton v)+ bindsVars (Let v _ a) = a |-> Set.singleton v instance HasVars LetRec Var where- bindsVars (LetRec v a b) = Map.fromList [(a,vs),(b,vs)]+ bindsVars (LetRec v a b) = a |-> vs & b |-> vs where vs = Set.singleton v -- let x = x + 1 in (\y. y + x) z
testsuite/tests/Data/Comp_Test.hs view
@@ -6,6 +6,7 @@ import qualified Data.Comp.Examples_Test import qualified Data.Comp.Variables_Test import qualified Data.Comp.Multi_Test+import qualified Data.Comp.Subsume_Test -------------------------------------------------------------------------------- -- Test Suits@@ -17,7 +18,8 @@ Data.Comp.Equality_Test.tests, Data.Comp.Examples_Test.tests, Data.Comp.Variables_Test.tests,- Data.Comp.Multi_Test.tests+ Data.Comp.Multi_Test.tests,+ Data.Comp.Subsume_Test.tests ] --------------------------------------------------------------------------------
testsuite/tests/Test/Utils.hs view
@@ -1,22 +1,23 @@-{-# LANGUAGE TemplateHaskell, TypeOperators, FlexibleContexts, FlexibleInstances #-}+{-# LANGUAGE TemplateHaskell, TypeOperators, FlexibleContexts, FlexibleInstances, ConstraintKinds #-}+{-# LANGUAGE DeriveFunctor #-} module Test.Utils where import Data.Comp import Data.Comp.Derive -import Data.Foldable - data Tree l e = Leaf l | UnNode l e | BinNode e l e | TerNode l e e e+ deriving Functor data Pair a e = Pair a e+ deriving Functor $(derive- [makeFunctor, makeFoldable, makeShowF, makeEqF, makeArbitraryF]+ [makeFoldable, makeShowF, makeEqF, makeArbitraryF] [''Tree, ''Pair]) $(derive