packages feed

th-sccs (empty) → 0.0.0.20110217

raw patch · 4 files changed

+219/−0 lines, 4 filesdep +basedep +containersdep +template-haskellsetup-changed

Dependencies added: base, containers, template-haskell

Files

+ LICENSE view
@@ -0,0 +1,28 @@+Copyright (c) 2010 The University of Kansas+All rights reserved.++Redistribution and use in source and binary forms, with or without modification,+are permitted provided that the following conditions are met:++1. Redistributions of source code must retain the above copyright notice, this+   list of conditions and the following disclaimer.++2. Redistributions in binary form must reproduce the above copyright notice,+   this list of conditions and the following disclaimer in the documentation+   and/or other materials provided with the distribution.++3. Neither the name of The University of Kansas nor the names of its contributors+   may be used to endorse or promote products derived from this software without+   specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.+
+ Language/Haskell/TH/SCCs.hs view
@@ -0,0 +1,148 @@+module Language.Haskell.TH.SCCs+  (binding_group, binding_groups,+   scc, sccs,+   Dependencies(..), type_dependencies,+   printQ+  ) where++import Language.Haskell.TH.Syntax++import qualified Data.Set as Set; import Data.Set (Set)+import qualified Data.Map as Map+import qualified Data.Traversable as Traversable+import Control.Monad (liftM, liftM2, (<=<))++import Data.Graph (stronglyConnComp, SCC(..))++++printQ s m = do+ x <- m+ runIO (maybe (return ()) putStr s >> print x) >> return []++++binding_group :: Name -> Q (Set Name)+binding_group = liftM binding_group' . scc++binding_groups :: [Name] -> Q [Set Name]+binding_groups ns = (filter relevant . map binding_group') `liftM` sccs ns+  where relevant bg = not (Set.null (Set.intersection (Set.fromList ns) bg))++binding_group' = either Set.singleton id++scc :: Name -> Q (Either Name (Set Name))+scc n = (head . filter (either (==n) (Set.member n))) `liftM` sccs [n]+  ++sccs :: [Name] -> Q [Either Name (Set Name)]+sccs ns = do+  let withK f k = (,) k `liftM` f k+      chaotic f = loop <=< analyze where+        analyze = Traversable.mapM f . Map.fromList .+                  map (\ x -> (x, x)) . Set.toList+        loop m | Set.null fringe = return m+               | otherwise = Map.union m `liftM` analyze fringe >>= loop+          where fringe =+                  Set.unions (Map.elems m) `Set.difference` Map.keysSet m+  names <- chaotic (type_dependencies <=< reify) (Set.fromList ns)+  let listify (AcyclicSCC v) = Left v+      listify (CyclicSCC vs) = Right (Set.fromList vs)+  return (map listify (stronglyConnComp [(n, n, Set.toList deps) |+                                         (n, deps) <- Map.assocs names]))++++class Named t where name_of :: t -> Name++instance Named Info where+  name_of i = case i of+    ClassI d -> name_of d+    ClassOpI n _ _ _ -> n+    TyConI d -> name_of d+    PrimTyConI n _ _ -> n+    DataConI n _ _ _ -> n+    VarI n _ _ _ -> n+    TyVarI n _ -> n++instance Named Dec where+  name_of d = case d of+    FunD n _ -> n+    ValD p _ _ -> name_of p+    DataD _ n _ _ _ -> n+    NewtypeD _ n _ _ _ -> n+    TySynD n _ _ -> n+    ClassD _ n _ _ _ -> n+    FamilyD _ n _ _ -> n+    o -> error $ show o ++ " is not a named declaration."++instance Named Con where+  name_of c = case c of+    NormalC n _ -> n+    RecC n _ -> n+    InfixC _ n _ -> n+    ForallC _ _ c -> name_of c++instance Named Pat where+  name_of p = case p of+    VarP n -> n+    AsP n _ -> n+    SigP p _ -> name_of p+    o -> error $ "The pattern `" ++ show o ++ "' does not define exactly one name."++++-- | Calculate the type declaration upon which this syntactic construct+-- syntactically dependends.+class Dependencies t where+  type_dependencies' :: [Name] -> t -> Q (Set Name)++type_dependencies :: Dependencies t => t -> Q (Set Name)+type_dependencies = type_dependencies' []++++recur ns = type_dependencies' ns+recur' ns x = type_dependencies' (ns ++ [name_of x])++instance Dependencies Info where+  type_dependencies' ns i = case i of+    TyConI d -> recur' ns i d+    PrimTyConI n _ _ -> return Set.empty+    _ -> error $ "This version of th-sccs only calculates mutually " +++                 "recursive groups for types; " ++ show (name_of i) +++                 " is not a type."++instance Dependencies Dec where+  type_dependencies' ns d = case d of+    DataD _ _ _ cons _ -> Set.unions `liftM` mapM w cons+    NewtypeD _ _ _ c _ -> w c+    TySynD _ _ ty -> w ty+    FamilyD {} ->+      error $ "This version of th-sccs cannot calculate mutually recursive " +++              "groups for types involving type families; " +++              show (last ns) ++ " uses " ++ show (name_of d) ++ "."+    o -> error $ "Unexpected declaration: " ++ show o ++ "."+    where w x = recur' ns d x++instance Dependencies Con where+  type_dependencies' ns c = case c of+    NormalC _ sts -> w $ map snd sts+    RecC _ vsts -> w $ map (\ (n, _, t) -> RecordField n t) vsts+    InfixC stL _ stR -> w $ map snd [stL, stR]+    ForallC _ _ c -> type_dependencies' ns c+    where w xs = Set.unions `liftM` mapM (recur' ns c) xs++data RecordField = RecordField Name Type+instance Named RecordField where name_of (RecordField n _) = n+instance Dependencies RecordField where+  type_dependencies' ns rf@(RecordField _ ty) = recur' ns rf ty++instance Dependencies Type where+  type_dependencies' ns t = case t of+    ForallT _ _ t -> w t+    ConT n -> return (Set.singleton n)+    AppT tfn targ -> liftM2 Set.union (w tfn) (w targ)+    SigT t _ -> w t+    _ -> return Set.empty+    where w x = recur ns x
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ th-sccs.cabal view
@@ -0,0 +1,41 @@+Name:          th-sccs+Version:       0.0.0.20110217++Stability:     experimental++Synopsis: Binding group analysis in Template Haskell++Description: th-sccs exposes Template Haskell functions for computing the+             mutually recursive binding groups for data and type synonym+             declarations, excluding those that use type families.+             +             This includes a convenient type class for gathering the type+             constructor names that occur within a TH @Info@\/@Dec@\/@Type@+             value.++Author:        nfrisby@ittc.ku.edu+Maintainer:    nfrisby@ittc.ku.edu++Copyright:     (c) 2011 The University of Kansas+License:       BSD3+License-File:  LICENSE++++Category: Template Haskell++Cabal-version: >= 1.6.0.1+Build-Type:    Simple++++source-repository head+  type: git+  location: git@gitsldg.ittc.ku.edu:th-kind-workaround/th-sccs.git++Library+  Build-Depends: base >= 4 && < 5+  Build-Depends: containers+  Build-Depends: template-haskell++  Exposed-Modules: Language.Haskell.TH.SCCs