diff --git a/singletons.cabal b/singletons.cabal index b09b43d9..c01b39d7 100644 --- a/singletons.cabal +++ b/singletons.cabal @@ -44,7 +44,7 @@ library mtl >= 2.1.2, template-haskell, containers >= 0.5, - th-desugar >= 1.4.3 + th-desugar >= 1.5 && < 1.6 default-language: Haskell2010 other-extensions: TemplateHaskell -- TemplateHaskell must be listed in cabal file to work with diff --git a/src/Data/Promotion/Prelude/List.hs b/src/Data/Promotion/Prelude/List.hs index 52adefd3..93b43fec 100644 --- a/src/Data/Promotion/Prelude/List.hs +++ b/src/Data/Promotion/Prelude/List.hs @@ -225,7 +225,6 @@ module Data.Promotion.Prelude.List ( ) where import Data.Singletons.Prelude.Base -import Data.Singletons.Prelude.Bool import Data.Singletons.Prelude.Eq import Data.Promotion.Prelude.Ord import Data.Singletons.Prelude.List @@ -238,7 +237,7 @@ import Data.Singletons.Prelude.Num import Data.Maybe (listToMaybe) -- these imports are required fir functions that singletonize but are used -- in this module by a function that can't be singletonized -import Data.List (deleteBy, sortBy, insertBy) +import Data.List (sortBy, insertBy) $(promoteOnly [d| -- Can't be promoted because of limitations of Int promotion diff --git a/src/Data/Singletons/CustomStar.hs b/src/Data/Singletons/CustomStar.hs index 5d835f50..4aa138dd 100644 --- a/src/Data/Singletons/CustomStar.hs +++ b/src/Data/Singletons/CustomStar.hs @@ -24,7 +24,6 @@ module Data.Singletons.CustomStar ( ) where import Language.Haskell.TH -import Language.Haskell.TH.Syntax ( Quasi(..) ) import Data.Singletons.Util import Data.Singletons.Promote import Data.Singletons.Promote.Monad @@ -36,7 +35,6 @@ import Control.Monad import Data.Maybe import Control.Applicative import Language.Haskell.TH.Desugar -import Language.Haskell.TH.Desugar.Sweeten import Data.Singletons.Prelude.Eq import Data.Singletons.Prelude.Bool @@ -66,7 +64,7 @@ import Data.Singletons.Prelude.Bool -- @Bool@, and @Maybe@, not just promoted data constructors. -- -- Please note that this function is /very/ experimental. Use at your own risk. -singletonStar :: Quasi q +singletonStar :: DsMonad q => [Name] -- ^ A list of Template Haskell @Name@s for types -> q [Dec] singletonStar names = do @@ -76,13 +74,13 @@ singletonStar names = do [''Eq, ''Show, ''Read] fakeCtors <- zipWithM (mkCtor False) names kinds let dataDecl = DataDecl Data repName [] fakeCtors [''Show, ''Read , ''Eq, ''Ord] - promDecls <- promoteM_ $ promoteDataDec dataDecl - singletonDecls <- singDecsM $ singDataD dataDecl + promDecls <- promoteM_ [] $ promoteDataDec dataDecl + singletonDecls <- singDecsM [] $ singDataD dataDecl return $ decsToTH $ repDecl : promDecls ++ singletonDecls where -- get the kinds of the arguments to the tycon with the given name - getKind :: Quasi q => Name -> q [DKind] + getKind :: DsMonad q => Name -> q [DKind] getKind name = do info <- reifyWithWarning name dinfo <- dsInfo info @@ -99,7 +97,7 @@ singletonStar names = do -- first parameter is whether this is a real ctor (with a fresh name) -- or a fake ctor (when the name is actually a Haskell type) - mkCtor :: Quasi q => Bool -> Name -> [DKind] -> q DCon + mkCtor :: DsMonad q => Bool -> Name -> [DKind] -> q DCon mkCtor real name args = do (types, vars) <- evalForPair $ mapM kindToType args dataName <- if real then mkDataName (nameBase name) else return name @@ -107,7 +105,7 @@ singletonStar names = do DNormalC (map (\ty -> (NotStrict, ty)) types) -- demote a kind back to a type, accumulating any unbound parameters - kindToType :: Quasi q => DKind -> QWithAux [Name] q DType + kindToType :: DsMonad q => DKind -> QWithAux [Name] q DType kindToType (DForallK _ _) = fail "Explicit forall encountered in kind" kindToType (DVarK n) = do addElement n diff --git a/src/Data/Singletons/Prelude/List.hs b/src/Data/Singletons/Prelude/List.hs index a1bb4729..501c228e 100644 --- a/src/Data/Singletons/Prelude/List.hs +++ b/src/Data/Singletons/Prelude/List.hs @@ -21,7 +21,7 @@ -- ---------------------------------------------------------------------------- -module Data.Singletons.Prelude.List {-( +module Data.Singletons.Prelude.List ( -- * The singleton for lists Sing(SNil, SCons), -- | Though Haddock doesn't show it, the 'Sing' instance above declares @@ -75,7 +75,7 @@ module Data.Singletons.Prelude.List {-( -- * Searching lists -- ** Searching by equality -{- Elem, sElem, -} NotElem, sNotElem, Lookup, sLookup, + Elem, sElem, NotElem, sNotElem, Lookup, sLookup, -- ** Searching with a predicate Find, sFind, Filter, sFilter, Partition, sPartition, @@ -90,7 +90,7 @@ module Data.Singletons.Prelude.List {-( -- * Special lists -- ** \"Set\" operations -{- Nub, sNub, -} Delete, sDelete, (:\\), (%:\\), Union, sUnion, + Nub, sNub, Delete, sDelete, (:\\), (%:\\), Union, sUnion, Intersect, sIntersect, -- ** Ordered lists @@ -148,7 +148,7 @@ module Data.Singletons.Prelude.List {-( IsSuffixOfSym0, IsSuffixOfSym1, IsSuffixOfSym2, IsInfixOfSym0, IsInfixOfSym1, IsInfixOfSym2, -{- ElemSym0, ElemSym1, ElemSym2, -} + ElemSym0, ElemSym1, ElemSym2, NotElemSym0, NotElemSym1, NotElemSym2, ZipSym0, ZipSym1, ZipSym2, @@ -188,7 +188,7 @@ module Data.Singletons.Prelude.List {-( FindSym0, FindSym1, FindSym2, FilterSym0, FilterSym1, FilterSym2, PartitionSym0, PartitionSym1, PartitionSym2, -{- + Zip4Sym0, Zip4Sym1, Zip4Sym2, Zip4Sym3, Zip4Sym4, Zip5Sym0, Zip5Sym1, Zip5Sym2, Zip5Sym3, Zip5Sym4, Zip5Sym5, Zip6Sym0, Zip6Sym1, Zip6Sym2, Zip6Sym3, Zip6Sym4, Zip6Sym5, Zip6Sym6, @@ -203,16 +203,16 @@ module Data.Singletons.Prelude.List {-( ZipWith6Sym5, ZipWith6Sym6, ZipWith6Sym7, ZipWith7Sym0, ZipWith7Sym1, ZipWith7Sym2, ZipWith7Sym3, ZipWith7Sym4, ZipWith7Sym5, ZipWith7Sym6, ZipWith7Sym7, ZipWith7Sym8, --} -{- NubSym0, NubSym1, -} + + NubSym0, NubSym1, NubBySym0, NubBySym1, NubBySym2, UnionBySym0, UnionBySym1, UnionBySym2, UnionBySym3, UnionSym0, UnionSym1, UnionSym2, IntersectSym0, IntersectSym1, IntersectSym2, IntersectBySym0, IntersectBySym1, IntersectBySym2, IntersectBySym3 - )-} where + ) where import Data.Singletons import Data.Singletons.Prelude.Instances @@ -444,7 +444,7 @@ $(singletonsOnly [d| unzip :: [(a,b)] -> ([a],[b]) unzip xs = foldr (\(a,b) (as,bs) -> (a:as,b:bs)) ([],[]) xs -{- + -- Lazy patterns removed from unzip unzip3 :: [(a,b,c)] -> ([a],[b],[c]) unzip3 xs = foldr (\(a,b,c) (as,bs,cs) -> (a:as,b:bs,c:cs)) @@ -469,7 +469,7 @@ $(singletonsOnly [d| unzip7 xs = foldr (\(a,b,c,d,e,f,g) (as,bs,cs,ds,es,fs,gs) -> (a:as,b:bs,c:cs,d:ds,e:es,f:fs,g:gs)) ([],[],[],[],[],[],[]) xs --} + -- We can't promote any of these functions because at the type level -- String literals are no longer considered to be lists of Chars, so -- there is mismatch between term-level and type-level semantics @@ -603,7 +603,7 @@ $(singletonsOnly [d| select :: (a -> Bool) -> a -> ([a], [a]) -> ([a], [a]) select p x ~(ts,fs) | p x = (x:ts,fs) | otherwise = (ts, x:fs) -{- + zip4 :: [a] -> [b] -> [c] -> [d] -> [(a,b,c,d)] zip4 = zipWith4 (,,,) @@ -640,7 +640,6 @@ $(singletonsOnly [d| zipWith7 z (a:as) (b:bs) (c:cs) (d:ds) (e:es) (f:fs) (g:gs) = z a b c d e f g : zipWith7 z as bs cs ds es fs gs zipWith7 _ _ _ _ _ _ _ _ = [] --} nub :: (Eq a) => [a] -> [a] nub l = nub' l [] diff --git a/src/Data/Singletons/Promote.hs b/src/Data/Singletons/Promote.hs index e3c38b98..80cf145a 100644 --- a/src/Data/Singletons/Promote.hs +++ b/src/Data/Singletons/Promote.hs @@ -14,7 +14,6 @@ module Data.Singletons.Promote where import Language.Haskell.TH hiding ( Q, cxt ) import Language.Haskell.TH.Syntax ( Quasi(..), lift ) import Language.Haskell.TH.Desugar -import Language.Haskell.TH.Desugar.Sweeten import Language.Haskell.TH.Desugar.Lift () import Data.Singletons.Names import Data.Singletons.Promote.Monad @@ -33,52 +32,52 @@ import Data.Map.Strict ( Map ) -- | Generate promoted definitions from a type that is already defined. -- This is generally only useful with classes. -genPromotions :: Quasi q => [Name] -> q [Dec] +genPromotions :: DsMonad q => [Name] -> q [Dec] genPromotions names = do checkForRep names infos <- mapM reifyWithWarning names dinfos <- mapM dsInfo infos - ddecs <- promoteM_ $ mapM_ promoteInfo dinfos + ddecs <- promoteM_ [] $ mapM_ promoteInfo dinfos return $ decsToTH ddecs -- | Promote every declaration given to the type level, retaining the originals. -promote :: Quasi q => q [Dec] -> q [Dec] +promote :: DsMonad q => q [Dec] -> q [Dec] promote qdec = do decls <- qdec - ddecls <- dsDecs decls - promDecls <- promoteM_ $ promoteDecs ddecls + ddecls <- withLocalDeclarations decls $ dsDecs decls + promDecls <- promoteM_ decls $ promoteDecs ddecls return $ decls ++ decsToTH promDecls -- | Promote each declaration, discarding the originals. -promoteOnly :: Quasi q => q [Dec] -> q [Dec] +promoteOnly :: DsMonad q => q [Dec] -> q [Dec] promoteOnly qdec = do decls <- qdec ddecls <- dsDecs decls - promDecls <- promoteM_ $ promoteDecs ddecls + promDecls <- promoteM_ decls $ promoteDecs ddecls return $ decsToTH promDecls -- | Generate defunctionalization symbols for existing type family -genDefunSymbols :: Quasi q => [Name] -> q [Dec] +genDefunSymbols :: DsMonad q => [Name] -> q [Dec] genDefunSymbols names = do checkForRep names infos <- mapM (dsInfo <=< reifyWithWarning) names - decs <- promoteMDecs $ concatMapM defunInfo infos + decs <- promoteMDecs [] $ concatMapM defunInfo infos return $ decsToTH decs -- | Produce instances for '(:==)' (type-level equality) from the given types -promoteEqInstances :: Quasi q => [Name] -> q [Dec] +promoteEqInstances :: DsMonad q => [Name] -> q [Dec] promoteEqInstances = concatMapM promoteEqInstance -- | Produce instances for 'Compare' from the given types -promoteOrdInstances :: Quasi q => [Name] -> q [Dec] +promoteOrdInstances :: DsMonad q => [Name] -> q [Dec] promoteOrdInstances = concatMapM promoteOrdInstance -- | Produce instances for 'MinBound' and 'MaxBound' from the given types -promoteBoundedInstances :: Quasi q => [Name] -> q [Dec] +promoteBoundedInstances :: DsMonad q => [Name] -> q [Dec] promoteBoundedInstances = concatMapM promoteBoundedInstance -- | Produce an instance for '(:==)' (type-level equality) from the given type -promoteEqInstance :: Quasi q => Name -> q [Dec] +promoteEqInstance :: DsMonad q => Name -> q [Dec] promoteEqInstance name = do (_tvbs, cons) <- getDataD "I cannot make an instance of (:==) for it." name cons' <- mapM dsCon cons @@ -88,7 +87,7 @@ promoteEqInstance name = do return $ decsToTH inst_decs -- | Produce an instance for 'Compare' from the given type -promoteOrdInstance :: Quasi q => Name -> q [Dec] +promoteOrdInstance :: DsMonad q => Name -> q [Dec] promoteOrdInstance name = do (_tvbs, cons) <- getDataD "I cannot make an instance of Ord for it." name cons' <- mapM dsCon cons @@ -98,7 +97,7 @@ promoteOrdInstance name = do return $ decsToTH inst_decs -- | Produce an instance for 'MinBound' and 'MaxBound' from the given type -promoteBoundedInstance :: Quasi q => Name -> q [Dec] +promoteBoundedInstance :: DsMonad q => Name -> q [Dec] promoteBoundedInstance name = do (_tvbs, cons) <- getDataD "I cannot make an instance of Bounded for it." name cons' <- mapM dsCon cons diff --git a/src/Data/Singletons/Promote/Monad.hs b/src/Data/Singletons/Promote/Monad.hs index 90d0a038..5e6e0295 100644 --- a/src/Data/Singletons/Promote/Monad.hs +++ b/src/Data/Singletons/Promote/Monad.hs @@ -35,11 +35,13 @@ type LetExpansions = Map Name DType -- from **term-level** name data PrEnv = PrEnv { pr_lambda_bound :: Map Name Name , pr_let_bound :: LetExpansions + , pr_local_decls :: [Dec] } emptyPrEnv :: PrEnv emptyPrEnv = PrEnv { pr_lambda_bound = Map.empty - , pr_let_bound = Map.empty } + , pr_let_bound = Map.empty + , pr_local_decls = [] } -- the promotion monad newtype PrM a = PrM (ReaderT PrEnv (WriterT [DDec] Q) a) @@ -74,6 +76,9 @@ instance Quasi PrM where tell aux return result +instance DsMonad PrM where + localDeclarations = asks pr_local_decls + -- return *type-level* names allLocals :: MonadReader PrEnv m => m [Name] allLocals = do @@ -117,20 +122,20 @@ lookupVarE n = do Just ty -> return ty Nothing -> return $ promoteValRhs n -promoteM :: Quasi q => PrM a -> q (a, [DDec]) -promoteM (PrM rdr) = - let wr = runReaderT rdr emptyPrEnv +promoteM :: DsMonad q => [Dec] -> PrM a -> q (a, [DDec]) +promoteM locals (PrM rdr) = do + other_locals <- localDeclarations + let wr = runReaderT rdr (emptyPrEnv { pr_local_decls = other_locals ++ locals }) q = runWriterT wr - in runQ q -promoteM_ :: Quasi q => PrM () -> q [DDec] -promoteM_ thing = do - ((), decs) <- promoteM thing +promoteM_ :: DsMonad q => [Dec] -> PrM () -> q [DDec] +promoteM_ locals thing = do + ((), decs) <- promoteM locals thing return decs -- promoteM specialized to [DDec] -promoteMDecs :: Quasi q => PrM [DDec] -> q [DDec] -promoteMDecs thing = do - (decs1, decs2) <- promoteM thing +promoteMDecs :: DsMonad q => [Dec] -> PrM [DDec] -> q [DDec] +promoteMDecs locals thing = do + (decs1, decs2) <- promoteM locals thing return $ decs1 ++ decs2 diff --git a/src/Data/Singletons/Single.hs b/src/Data/Singletons/Single.hs index ad62e194..b0437d3a 100644 --- a/src/Data/Singletons/Single.hs +++ b/src/Data/Singletons/Single.hs @@ -24,7 +24,6 @@ import Data.Singletons.Single.Eq import Data.Singletons.Single.Squash import Data.Singletons.Syntax import Language.Haskell.TH.Desugar -import Language.Haskell.TH.Desugar.Sweeten import qualified Data.Map.Strict as Map import Data.Map.Strict ( Map ) import Control.Monad @@ -131,13 +130,13 @@ singEqualityInstance desc@(_, className, _) name = do kind = DConK name tyvars aName <- qNewName "a" let aVar = DVarT aName - (scons, _) <- singM $ mapM (singCtor aVar) dcons + (scons, _) <- singM [] $ mapM (singCtor aVar) dcons eqInstance <- mkEqualityInstance kind scons desc return $ decToTH eqInstance singInfo :: DsMonad q => DInfo -> q [DDec] singInfo (DTyConI dec Nothing) = do -- TODO: document this special case - singTopLevelDecs [dec] + singTopLevelDecs [] [dec] singInfo (DTyConI {}) = fail "Singling of things with instances not yet supported" -- TODO: fix singInfo (DPrimTyConI _name _numArgs _unlifted) = @@ -147,8 +146,8 @@ singInfo (DVarI _name _ty _mdec _fixity) = singInfo (DTyVarI _name _ty) = fail "Singling of type variable info not supported" -singTopLevelDecs :: DsMonad q => [DDec] -> q [DDec] -singTopLevelDecs decls = do +singTopLevelDecs :: DsMonad q => [Dec] -> [DDec] -> q [DDec] +singTopLevelDecs locals decls = do PDecs { pd_let_decs = letDecls , pd_class_decs = classes , pd_instance_decs = insts @@ -159,9 +158,10 @@ singTopLevelDecs decls = do when (not (null classes) || not (null insts)) $ qReportError "Classes and instances may not yet be made into singletons." - dataDecls' <- promoteM_ $ promoteDataDecs datas - ((_, letDecEnv), letDecls') <- promoteM $ promoteLetDecs noPrefix squashedLetDecls - singDecsM $ do + dataDecls' <- promoteM_ locals $ promoteDataDecs datas + ((_, letDecEnv), letDecls') <- promoteM locals $ + promoteLetDecs noPrefix squashedLetDecls + singDecsM locals $ do let letBinds = concatMap buildDataLets datas ++ concatMap buildMethLets classes (newLetDecls, newDataDecls) <- bindLets letBinds $ diff --git a/src/Data/Singletons/Single/Monad.hs b/src/Data/Singletons/Single/Monad.hs index f4559e29..faae56b8 100644 --- a/src/Data/Singletons/Single/Monad.hs +++ b/src/Data/Singletons/Single/Monad.hs @@ -33,11 +33,13 @@ import Control.Monad.Writer -- environment during singling data SgEnv = - SgEnv { sg_let_binds :: Map Name DExp -- from the *original* name + SgEnv { sg_let_binds :: Map Name DExp -- from the *original* name + , sg_local_decls :: [Dec] } emptySgEnv :: SgEnv -emptySgEnv = SgEnv { sg_let_binds = Map.empty +emptySgEnv = SgEnv { sg_let_binds = Map.empty + , sg_local_decls = [] } -- the singling monad @@ -73,6 +75,9 @@ instance Quasi SgM where tell aux return result +instance DsMonad SgM where + localDeclarations = asks sg_local_decls + bindLets :: [(Name, DExp)] -> SgM a -> SgM a bindLets lets1 = local (\env@(SgEnv { sg_let_binds = lets2 }) -> @@ -148,7 +153,7 @@ lookup_var_con mk_sing_name mk_exp name = do case Map.lookup name letExpansions of Nothing -> do -- try to get it from the global context - m_dinfo <- qReifyMaybe sName + m_dinfo <- dsReify sName case m_dinfo of Just (DVarI _ ty _ _) -> let num_args = countArgs ty in @@ -188,14 +193,14 @@ wrapUnSingFun n ty = in (unwrap_fun `DAppE` proxyFor ty `DAppE`) -singM :: Quasi q => SgM a -> q (a, [DDec]) -singM (SgM rdr) = - let wr = runReaderT rdr emptySgEnv +singM :: DsMonad q => [Dec] -> SgM a -> q (a, [DDec]) +singM locals (SgM rdr) = do + other_locals <- localDeclarations + let wr = runReaderT rdr (emptySgEnv { sg_local_decls = other_locals ++ locals }) q = runWriterT wr - in runQ q -singDecsM :: Quasi q => SgM [DDec] -> q [DDec] -singDecsM thing = do - (decs1, decs2) <- singM thing +singDecsM :: DsMonad q => [Dec] -> SgM [DDec] -> q [DDec] +singDecsM locals thing = do + (decs1, decs2) <- singM locals thing return $ decs1 ++ decs2 diff --git a/src/Data/Singletons/Single/Squash.hs b/src/Data/Singletons/Single/Squash.hs index de1fb23f..ae2b8b5d 100644 --- a/src/Data/Singletons/Single/Squash.hs +++ b/src/Data/Singletons/Single/Squash.hs @@ -15,7 +15,6 @@ import Prelude hiding ( exp ) import Language.Haskell.TH.Desugar import Control.Applicative import Control.Monad -import Language.Haskell.TH.Desugar.Match import Data.Singletons.Util import Data.Singletons.Names import qualified Data.Set as Set diff --git a/src/Data/Singletons/Syntax.hs b/src/Data/Singletons/Syntax.hs index 4086b4c5..92898091 100644 --- a/src/Data/Singletons/Syntax.hs +++ b/src/Data/Singletons/Syntax.hs @@ -18,7 +18,6 @@ import Data.Singletons.Util import Language.Haskell.TH.Syntax import Language.Haskell.TH.Desugar import Language.Haskell.TH.Ppr -import Language.Haskell.TH.Desugar.Sweeten import Data.Map.Strict ( Map ) import qualified Data.Map.Strict as Map import Data.Maybe diff --git a/src/Data/Singletons/TH.hs b/src/Data/Singletons/TH.hs index 5ba0fc6f..80cad2a3 100644 --- a/src/Data/Singletons/TH.hs +++ b/src/Data/Singletons/TH.hs @@ -77,11 +77,9 @@ import Data.Singletons.Decide import Data.Singletons.TypeLits import Data.Singletons.SuppressUnusedWarnings import Language.Haskell.TH.Desugar -import Language.Haskell.TH.Desugar.Sweeten import GHC.Exts import Language.Haskell.TH -import Language.Haskell.TH.Syntax ( Quasi(..) ) import Data.Singletons.Util import Data.Proxy ( Proxy(..) ) import Control.Applicative @@ -90,13 +88,13 @@ import Control.Applicative -- is identical. This may be useful if the type-checker requires knowledge of which -- constructor is used to satisfy equality or type-class constraints, but where -- each constructor is treated the same. -cases :: Quasi q +cases :: DsMonad q => Name -- ^ The head of the type of the scrutinee. (Like @''Maybe@ or @''Bool@.) -> q Exp -- ^ The scrutinee, in a Template Haskell quote -> q Exp -- ^ The body, in a Template Haskell quote -> q Exp cases tyName expq bodyq = do - info <- reifyWithWarning tyName + info <- reifyWithLocals tyName dinfo <- dsInfo info case dinfo of DTyConI (DDataD _ _ _ _ ctors _) _ -> fmap expToTH $ buildCases ctors diff --git a/src/Data/Singletons/Util.hs b/src/Data/Singletons/Util.hs index 0d8be9ae..33a1083e 100644 --- a/src/Data/Singletons/Util.hs +++ b/src/Data/Singletons/Util.hs @@ -46,11 +46,6 @@ boundedBasicTypes = [ ''Bool , ''(,,,,,,) ] -qReifyMaybe :: Quasi q => Name -> q (Maybe DInfo) -qReifyMaybe name = do - m_info <- qRecover (return Nothing) (fmap Just $ qReify name) - traverse dsInfo m_info - -- like reportWarning, but generalized to any Quasi qReportWarning :: Quasi q => String -> q () qReportWarning = qReport False @@ -242,16 +237,15 @@ multiCase scruts pats body = DCaseE (mkTupleDExp scruts) [DMatch (mkTupleDPat pats) body] -- Make a desugar function into a TH function. -wrapDesugar :: (Desugar th ds, Quasi q) => (ds -> q ds) -> th -> q th +wrapDesugar :: (Desugar th ds, DsMonad q) => (th -> ds -> q ds) -> th -> q th wrapDesugar f th = do ds <- desugar th - fmap sweeten $ f ds + fmap sweeten $ f th ds -- a monad transformer for writing a monoid alongside returning a Q newtype QWithAux m q a = QWA { runQWA :: WriterT m q a } - deriving (Functor, Applicative, Monad, MonadTrans, MonadWriter m) - -deriving instance (Monoid m, MonadReader r q) => MonadReader r (QWithAux m q) + deriving ( Functor, Applicative, Monad, MonadTrans + , MonadWriter m, MonadReader r ) -- make a Quasi instance for easy lifting instance (Quasi q, Monoid m) => Quasi (QWithAux m q) where @@ -276,6 +270,9 @@ instance (Quasi q, Monoid m) => Quasi (QWithAux m q) where tell aux return result +instance (DsMonad q, Monoid m) => DsMonad (QWithAux m q) where + localDeclarations = lift localDeclarations + -- helper functions for composition comp1 :: (b -> c) -> (a -> b) -> a -> c comp1 = (.) diff --git a/th-desugar b/th-desugar index a6c5dc5b..25e8d71e 160000 --- a/th-desugar +++ b/th-desugar @@ -1 +1 @@ -Subproject commit a6c5dc5bf5ce645cade0148d59151a0e4b2af557 +Subproject commit 25e8d71ef89292f8392a570b12fec483362bab21