packages feed

type-structure (empty) → 0.1.0

raw patch · 14 files changed

+868/−0 lines, 14 filesdep +HTFdep +HUnitdep +QuickChecksetup-changed

Dependencies added: HTF, HUnit, QuickCheck, QuickCheck-GenT, array, base, bytestring, containers, hashable, loch-th, mtl, placeholders, quickcheck-instances, template-haskell, text, th-instance-reification, time, transformers, unordered-containers, vector

Files

+ LICENSE view
@@ -0,0 +1,22 @@+Copyright (c) 2014, Nikita Volkov++Permission is hereby granted, free of charge, to any person+obtaining a copy of this software and associated documentation+files (the "Software"), to deal in the Software without+restriction, including without limitation the rights to use,+copy, modify, merge, publish, distribute, sublicense, and/or sell+copies of the Software, and to permit persons to whom the+Software is furnished to do so, subject to the following+conditions:++The above copyright notice and this permission notice shall be+included in all copies or substantial portions of the Software.++THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR+OTHER DEALINGS IN THE SOFTWARE.
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ src/HTFTestSuite.hs view
@@ -0,0 +1,9 @@+{-# OPTIONS_GHC -F -pgmF htfpp #-}++import Test.Framework+import TypeStructure.Prelude.Basic++import {-@ HTF_TESTS @-} TypeStructureTest+import {-@ HTF_TESTS @-} TypeStructure.THTest++main = htfMain $ htf_thisModulesTests : htf_importedTests
+ src/TypeStructure.hs view
@@ -0,0 +1,121 @@+module TypeStructure+(+  -- * Class+  TypeStructure(..), +  derive,+  -- * Model+  module TypeStructure.Model, +)+where++import TypeStructure.Prelude.Basic+import TypeStructure.Prelude.Data+import TypeStructure.Prelude.Transformers+import TypeStructure.Model+import TypeStructure.Class+import TypeStructure.TH+import qualified TypeStructure.Prelude.TH as TH+import qualified GHC.Exts+++-- base+---------------------+derive ''(->)+derive ''()+derive ''[]+derive ''Int+derive ''Int8+derive ''Int16+derive ''Int32+derive ''Int64+derive ''Integer+derive ''Word+derive ''Word8+derive ''Word16+derive ''Word32+derive ''Word64+derive ''Float+derive ''Double+derive ''Char+derive ''Bool+derive ''Ordering+derive ''Fixed+derive ''E0+derive ''E1+derive ''E2+derive ''E3+derive ''E6+derive ''E9+derive ''E12+derive ''Ratio+derive ''Last+derive ''First+derive ''Any+derive ''All+derive ''Sum+derive ''Product+derive ''Dual+derive ''Seq+derive ''Maybe+derive ''Either+derive ''GHC.Exts.Any+derive ''ThreadId+derive ''TypeRep+derive ''StableName++-- tuples+fmap join $ mapM derive $ map TH.tupleTypeName [2..24]++-- transformers+---------------------+derive ''Identity++-- vector+---------------------+derive ''Vector++-- array+---------------------+derive ''UArray+derive ''Array++-- containers+---------------------+derive ''IntSet+derive ''IntMap+derive ''Set+derive ''Tree+derive ''Map++-- unordered-containers+---------------------+derive ''HashSet+derive ''HashMap++-- bytestring+---------------------+derive ''ByteString+derive ''LazyByteString++-- text+---------------------+derive ''Text+derive ''LazyText++-- time+---------------------+derive ''AbsoluteTime+derive ''ZonedTime+derive ''LocalTime+derive ''TimeZone+derive ''TimeOfDay+derive ''NominalDiffTime+derive ''UTCTime+derive ''UniversalTime+derive ''DiffTime+derive ''Day++-- type-structure+---------------------+derive ''Type+derive ''Declaration
+ src/TypeStructure/Class.hs view
@@ -0,0 +1,16 @@+module TypeStructure.Class where++import TypeStructure.Prelude.Basic+import TypeStructure.Model+++-- |+-- A type structure graph production.+-- +-- Supposed to be used like this:+-- +-- @+-- graph (undefined :: Int)+-- @+class TypeStructure a where+  graph :: a -> Graph
+ src/TypeStructure/Model.hs view
@@ -0,0 +1,50 @@+module TypeStructure.Model where++import TypeStructure.Prelude.Basic+import TypeStructure.Prelude.Data+++-- |+-- A representation of the type structure graph.+-- +-- Consists of a type signature of the subject type and +-- a dictionary of all the types it refers to internally with+-- primitive types as end-nodes.+type Graph = (Type, Dictionary)++-- | A type signature.+data Type =+  Type_App Type Type |+  Type_Var TypeVar |+  Type_Con TypeCon+  deriving (Read, Show, Ord, Eq, Data, Typeable, Generic)++instance Hashable Type++-- | A type variable.+type TypeVar = Name++-- | A type constructor.+type TypeCon = (Namespace, Name)++-- | A name.+type Name = Text++-- | A namespace (module name).+type Namespace = Text++-- | A dictionary of type declarations indexed by type constructors.+type Dictionary = [(TypeCon, Declaration)]++-- | A type declaration.+data Declaration = +  Declaration_ADT [TypeVar] [Constructor] | +  Declaration_Primitive |+  Declaration_Synonym [TypeVar] Type+  deriving (Read, Show, Ord, Eq, Data, Typeable, Generic)++instance Hashable Declaration++-- | A data constructor used in type declaration.+type Constructor = (Name, [Type])+
+ src/TypeStructure/Prelude/Basic.hs view
@@ -0,0 +1,88 @@+module TypeStructure.Prelude.Basic+( +  module Exports,++  traceM,+  bug,+  bottom,++  (?:),+  (|>),+  (<|),+  (|$>),+)+where++-- base+import Prelude as Exports hiding (concat, foldr, mapM_, sequence_, foldl1, maximum, minimum, product, sum, all, and, any, concatMap, elem, foldl, foldr1, notElem, or, mapM, sequence, FilePath, id, (.))+import Control.Monad as Exports hiding (mapM_, sequence_, forM_, msum, mapM, sequence, forM)+import Control.Applicative as Exports+import Control.Arrow as Exports hiding (left, right)+import Control.Category as Exports+import Data.Monoid as Exports+import Data.Foldable as Exports+import Data.Traversable as Exports hiding (for)+import Data.Maybe as Exports+import Data.Either as Exports+import Data.List as Exports hiding (concat, foldr, foldl1, maximum, minimum, product, sum, all, and, any, concatMap, elem, foldl, foldr1, notElem, or, find, maximumBy, minimumBy, mapAccumL, mapAccumR, foldl')+import Data.Tuple as Exports+import Data.Ord as Exports (Down(..))+import Data.String as Exports+import Data.Int as Exports+import Data.Word as Exports+import Data.Ratio as Exports+import Data.Fixed as Exports+import Data.Ix as Exports+import Data.Data as Exports+import Text.Read as Exports (readMaybe, readEither)+import Control.Exception as Exports hiding (tryJust, try, assert)+import Control.Concurrent as Exports hiding (yield)+import System.Mem.StableName as Exports+import System.Timeout as Exports+import System.Exit as Exports+import System.IO.Unsafe as Exports+import System.IO as Exports (Handle, hClose)+import System.IO.Error as Exports+import Unsafe.Coerce as Exports+import GHC.Exts as Exports hiding (Any, traceEvent)+import GHC.Generics as Exports (Generic)+import GHC.IO.Exception as Exports+import Data.IORef as Exports+import Data.STRef as Exports+import Control.Monad.ST as Exports+import Debug.Trace as Exports++-- placeholders+import Development.Placeholders as Exports+++import qualified Debug.Trace.LocationTH++traceM :: (Monad m) => String -> m ()+traceM s = trace s $ return ()++bug = [e| $(Debug.Trace.LocationTH.failure) . (msg <>) |]+  where+    msg = "A \"type-structure\" package bug: " :: String++bottom = [e| $bug "Bottom evaluated" |]++(?:) :: Maybe a -> a -> a+maybeA ?: b = fromMaybe b maybeA+{-# INLINE (?:) #-}++(|>) :: a -> (a -> b) -> b+a |> aToB = aToB a+{-# INLINE (|>) #-}++(<|) :: (a -> b) -> a -> b+aToB <| a = aToB a+{-# INLINE (<|) #-}++-- | +-- The following are all the same:+-- fmap f a == f <$> a == a |> fmap f == a |$> f+-- +-- This operator accomodates the left-to-right operators: >>=, >>>, |>.+(|$>) = flip fmap+{-# INLINE (|$>) #-}
+ src/TypeStructure/Prelude/Data.hs view
@@ -0,0 +1,54 @@+module TypeStructure.Prelude.Data+(+  module Exports,++  LazyByteString,+  LazyText,+  packText,+  unpackText,+)+where++-- hashable+import Data.Hashable as Exports (Hashable(..), hash)++-- bytestring+import Data.ByteString as Exports (ByteString)++-- text+import Data.Text as Exports (Text)++-- containers+import Data.Map as Exports (Map)+import Data.IntMap as Exports (IntMap)+import Data.Set as Exports (Set)+import Data.IntSet as Exports (IntSet)+import Data.Sequence as Exports (Seq)+import Data.Tree as Exports (Tree)++-- unordered-containers+import Data.HashMap.Strict as Exports (HashMap)+import Data.HashSet as Exports (HashSet)++-- array+import Data.Array as Exports (Array)+import Data.Array.Unboxed as Exports (UArray)+import Data.Array.IArray as Exports (IArray)++-- vector+import Data.Vector as Exports (Vector)++-- time+import Data.Time as Exports (Day, DiffTime, NominalDiffTime, UniversalTime, UTCTime, LocalTime, TimeOfDay, TimeZone, ZonedTime)+import Data.Time.Clock.TAI as Exports (AbsoluteTime)+++import qualified Data.ByteString.Lazy+import qualified Data.Text.Lazy+import qualified Data.Text++type LazyByteString = Data.ByteString.Lazy.ByteString+type LazyText = Data.Text.Lazy.Text++packText = Data.Text.pack+unpackText = Data.Text.unpack
+ src/TypeStructure/Prelude/TH.hs view
@@ -0,0 +1,24 @@+module TypeStructure.Prelude.TH+(+  module Exports,++  purify,+  tryToReify,+  isProperInstance',+)+where++import TypeStructure.Prelude.Basic+import Language.Haskell.TH as Exports+import THInstanceReification as Exports+++purify :: Q a -> a+purify = unsafePerformIO . runQ++tryToReify :: Name -> Q (Maybe Info)+tryToReify n = recover (return Nothing) (fmap Just $ reify n) ++isProperInstance' :: Name -> [Type] -> Q Bool+isProperInstance' name types = recover (return False) (isProperInstance name types)+
+ src/TypeStructure/Prelude/Transformers.hs view
@@ -0,0 +1,9 @@+module TypeStructure.Prelude.Transformers (module Exports) where++import Control.Monad.Identity as Exports hiding (fail, mapM_, sequence_, forM_, msum, mapM, sequence, forM)+import Control.Monad.State as Exports hiding (fail, mapM_, sequence_, forM_, msum, mapM, sequence, forM)+import Control.Monad.Reader as Exports hiding (fail, mapM_, sequence_, forM_, msum, mapM, sequence, forM)+import Control.Monad.Writer as Exports hiding (fail, mapM_, sequence_, forM_, msum, mapM, sequence, forM, Any)+import Control.Monad.RWS as Exports hiding (fail, mapM_, sequence_, forM_, msum, mapM, sequence, forM, Any)+import Control.Monad.Cont as Exports hiding (fail, mapM_, sequence_, forM_, msum, mapM, sequence, forM)+import Control.Monad.Error as Exports hiding (fail, mapM_, sequence_, forM_, msum, mapM, sequence, forM)
+ src/TypeStructure/TH.hs view
@@ -0,0 +1,117 @@+module TypeStructure.TH where++import TypeStructure.Prelude.Basic+import TypeStructure.Prelude.Transformers+import TypeStructure.Prelude.Data+import TypeStructure.Prelude.TH+import qualified TypeStructure.Class as Class+import qualified TypeStructure.TH.Model as M+import qualified TypeStructure.TH.Template as Template+++-- |+-- Automatically derive the instance of 'Class.TypeStructure' using Template Haskell.+derive :: Name -> Q [Dec]+derive name = do+  typeCon <- deriveTypeCon name+  info <- reify name+  let+    declaration = infoToDeclaration info+    vars = case declaration of+      M.Primitive arity -> arity |> take |> ($ [0..]) |> map (show >>> ('_':))+      M.ADT vars _ -> vars+      M.Synonym vars _ -> vars+  (typesWithoutDictionaries, typesWithDictionaries) <- +    partitionEithers <$> +    execStateT (analyzeReferredTypes name) []+  inlinedRecords <- forM typesWithoutDictionaries $ \n -> do+    typeCon <- deriveTypeCon n+    declaration <- infoToDeclaration <$> reify n+    return (typeCon, declaration)+  return $ (:[]) $ Template.renderInstance +    name vars typeCon (nub $ (typeCon, declaration) : inlinedRecords) typesWithDictionaries+  where+    deriveTypeCon name = do+      ns <- maybe (fail "Name without namespace") return $ nameModule name+      return (ns, nameBase name)++analyzeReferredTypes :: +  Name -> +  StateT [Either Name Type] Q ()+analyzeReferredTypes name = do+  info <- lift $ reify $ name+  forM_ (referredTypes info) analyzeType+  where+    analyzeType t = do+      (lift $ isProperInstance' ''Class.TypeStructure [t]) >>= \case+        True -> void $ insert $ Right $ t+        False -> case t of+          AppT l r -> analyzeType l >> analyzeType r+          ConT n -> do+            inserted <- insert $ Left $ n+            when inserted $ analyzeReferredTypes n+          _ -> return ()+    insert a = state $ \list ->+      if elem a list+        then (False, list)+        else (True, a : list)++referredTypes :: Info -> [Type]+referredTypes = \case+  TyConI d -> case d of+    DataD _ _ _ cons _ -> conTypes =<< cons+    NewtypeD _ _ _ con _ -> conTypes $ con+    TySynD _ _ t -> [t]+    d -> $bug $ "Unsupported dec: " <> show d+  PrimTyConI n arity _ -> []+  i -> $bug $ "Unsupported info: " <> show i++conTypes :: Con -> [Type]+conTypes = \case+  NormalC n ts -> map snd ts+  RecC n ts -> map (\(_, _, t) -> t) ts+  InfixC (_, l) n (_, r) -> [l, r]+  c -> $bug $ "Unexpected constructor: " <> show c++adaptType :: Type -> M.Type+adaptType = \case+  AppT l r -> M.App (adaptType l) (adaptType r)+  VarT n -> M.Var $ nameBase $ n+  ConT n -> fromName n+  TupleT a -> fromName $ tupleTypeName a+  UnboxedTupleT a -> fromName $ unboxedTupleTypeName a+  ArrowT -> fromName ''(->)+  ListT -> fromName ''[]+  t -> $bug $ "Unsupported type: " <> show t+  where+    fromName n = +      M.Con $ +        adaptTypeConName n ?: +        ($bug $ "Name has no namespace: " <> show n)++adaptTypeConName :: Name -> Maybe M.TypeCon+adaptTypeConName n = do+  ns <- nameModule n+  return (ns, nameBase n)++infoToDeclaration :: Info -> M.Declaration+infoToDeclaration = \case+  TyConI d -> case d of+    DataD _ _ vars cons _ -> M.ADT (map adaptVar vars) (map adaptCon cons)+    NewtypeD _ _ vars con _ -> M.ADT (map adaptVar vars) [adaptCon con]+    TySynD _ vars t -> M.Synonym (map adaptVar vars) (adaptType t)+    d -> $bug $ "Unsupported dec: " <> show d+  PrimTyConI _ arity _ -> M.Primitive arity+  i -> $bug $ "Unsupported info: " <> show i++adaptVar :: TyVarBndr -> M.TypeVar+adaptVar = \case+  PlainTV n -> nameBase n+  KindedTV n k -> nameBase n++adaptCon :: Con -> M.Constructor+adaptCon = \case+  NormalC n ts -> (nameBase n, map (\(_, t) -> adaptType t) ts)+  RecC n ts -> (nameBase n, map (\(_, _, t) -> adaptType t) ts)+  InfixC (_, a) n (_, b) -> (nameBase n, [adaptType a, adaptType b])+  c -> $bug $ "Unexpected constructor: " <> show c
+ src/TypeStructure/TH/Model.hs view
@@ -0,0 +1,32 @@+module TypeStructure.TH.Model where++import TypeStructure.Prelude.Basic++-- NOTE!+-- Oddly enough, this model almost completely replicates the output Model itself, +-- so... Refactoring, baby!++data Type =+  App Type Type |+  Var TypeVar |+  Con TypeCon+  deriving (Show, Eq, Ord)++type TypeCon = (Namespace, Name)++type Namespace = String++type Name = String++type TypeVar = Name++data Declaration = +  Primitive Arity |+  ADT [TypeVar] [Constructor] |+  Synonym [TypeVar] Type+  deriving (Show, Eq, Ord)++type Arity = Int++type Constructor = (Name, [Type])+
+ src/TypeStructure/TH/Template.hs view
@@ -0,0 +1,141 @@++module TypeStructure.TH.Template where++import TypeStructure.Prelude.Basic+import TypeStructure.Prelude.Transformers+import TypeStructure.Prelude.Data+import TypeStructure.TH.Model+import qualified TypeStructure.Prelude.TH as T+import qualified TypeStructure.Model as M+import qualified TypeStructure.Class as C++-- |+-- 1.+-- @+-- Type_Var "a"+-- @+-- +-- 2.+-- @+-- Type_App (Type_Con ("GHC.Types", "[]")) (Type_Var "a")])+-- @+-- +renderType :: Type -> T.Exp+renderType = \case+  App l r -> T.purify [e| M.Type_App $(return $ renderType $ l) $(return $ renderType $ r) |]+  Var n -> T.purify [e| M.Type_Var $(T.stringE $ n) |]+  Con tcs -> T.purify [e| M.Type_Con $(return $ renderTypeCon tcs) |]++-- |+renderTypeCon :: TypeCon -> T.Exp+renderTypeCon (ns, n) = T.purify [e| ($(T.stringE ns), $(T.stringE n)) |]++-- |+-- Either+-- +-- @+-- let+--   vars = ["a"]+--   cons =+--     [("[]", []),+--      (":", +--       [Type_Var "a",+--        Type_App (Type_Con ("GHC.Types", "[]")) (Type_Var "a")])]+--   in Dec_ADT vars cons+-- @+-- +-- or+-- +-- @+-- Dec_Primitive+-- @+-- +renderDeclaration :: Declaration -> T.Exp+renderDeclaration = \case+  Primitive _ -> T.purify [e| M.Declaration_Primitive |]+  ADT vars constructors -> T.purify [e| M.Declaration_ADT $varsE $consE |] where+    varsE = T.listE $ map T.stringE vars+    consE = T.listE $ map renderCons constructors+      where+        renderCons (n, tss) = [e| ($nameE, $typesE) |] where+          nameE = T.stringE $ n+          typesE = T.listE $ map (return . renderType) tss+  Synonym vars t -> T.purify [e| M.Declaration_Synonym $varsE $typeE |] where+    varsE = T.listE $ map T.stringE vars+    typeE = return $ renderType t++-- |+-- @+-- instance TypeStructure a => TypeStructure (GHC.Types.[] a) where+--   graph = const $ (finalType, dictionary)+--     where+--       finalType = Type_App (Type_Con ("GHC.Types", "[]")) ((fst . graph) (undefined :: a))+--       dictionary = Data.HashMap.Strict.insert typeCon declaration inheritedDictionary+--         where+--           typeCon = ("GHC.Types", "[]")+--           declaration = +--             let+--               vars = ["a"]+--               cons =+--                 [("[]", []),+--                  (":", +--                   [Type_Var "a",+--                    Type_App (Type_Con ("GHC.Types", "[]")) (Type_Var "a")])]+--               in Dec_ADT vars cons+--           inheritedDictionary = mconcat [(snd . graph) (undefined :: a)]+-- @+-- +renderInstance+  :: T.Name -- ^ Type con +  -> [TypeVar]+  -> TypeCon+  -> [(TypeCon, Declaration)] -- ^ Records+  -> [T.Type] -- ^ TH Types to inherit dictionaries from+  -> T.Dec+renderInstance name vars tcs dictionaryRecords inheritedDictionaries =+  T.InstanceD +    context +    (T.ConT ''C.TypeStructure `T.AppT` headType) +    [graphDec]+  where+    context = flip map varTypes $ (T.ClassP ''C.TypeStructure . pure)+    varTypes = map (T.VarT . T.mkName) vars+    headType = foldl T.AppT (T.ConT name) varTypes+    graphDec = T.FunD 'C.graph [T.Clause [] (T.NormalB exp) [finalTypeDec, dictionaryDec, typeConDec]] +      where+        exp = T.purify $ [e| const ($(T.varE $ T.mkName "finalType"), $(T.varE $ T.mkName "dictionary")) |]+        finalTypeDec = T.FunD (T.mkName "finalType") [clause] where+          clause = T.Clause [] (T.NormalB exp) [] where+            exp = +              T.purify $+              foldM +                (\l r -> [e| M.Type_App $(return l) $(return r) |]) +                (T.purify [e| M.Type_Con $(T.varE $ T.mkName "typeCon") |])+                (map varExp varTypes)+              where+                varExp t = T.purify [e| ((fst . C.graph) (undefined :: $(return t))) |]+        dictionaryDec = T.FunD (T.mkName "dictionary") [T.Clause [] (T.NormalB exp) []] where+          exp = T.purify+            [e|+              let+                newRecords = $(+                    return $ T.ListE $ flip map dictionaryRecords $ \(tcs, ds) ->+                      T.purify +                        [e|+                          let +                            typeCon = $(return $ renderTypeCon tcs)+                            declaration = $(return $ renderDeclaration ds)+                            in (typeCon, declaration)+                        |]+                  )+                inheritedDictionary = +                  mconcat $ dicsOfTypeVars ++ dicsOfReferredTypes+                  where+                    dicsOfTypeVars = $(return $ T.ListE $ map dictionaryExp varTypes)+                    dicsOfReferredTypes = $(return $ T.ListE $ map dictionaryExp inheritedDictionaries)+                in foldr (\p -> (p:) . delete p) inheritedDictionary newRecords+            |]+            where+              dictionaryExp t = T.purify [e| ((snd . C.graph) (undefined :: $(return t))) |]+        typeConDec = T.FunD (T.mkName "typeCon") [T.Clause [] (T.NormalB exp) []] where+          exp = renderTypeCon tcs
+ type-structure.cabal view
@@ -0,0 +1,183 @@+name:+  type-structure+version:+  0.1.0+synopsis:+  Type structure analysis+description:+  Provides facilities to match type structures.++  Useful for checking protocol compliance in client-server applications.+category:+  Data+homepage:+  https://github.com/nikita-volkov/type-structure +bug-reports:+  https://github.com/nikita-volkov/type-structure/issues +author:+  Nikita Volkov <nikita.y.volkov@mail.ru>+maintainer:+  Nikita Volkov <nikita.y.volkov@mail.ru>+copyright:+  (c) 2014, Nikita Volkov+license:+  MIT+license-file:+  LICENSE+build-type:+  Simple+cabal-version:+  >=1.10+++source-repository head+  type:+    git+  location:+    git://github.com/nikita-volkov/type-structure.git+++library+  hs-source-dirs:+    src+  other-modules:+    TypeStructure.TH.Model+    TypeStructure.TH.Template+    TypeStructure.TH+    TypeStructure.Model+    TypeStructure.Class+    TypeStructure.Prelude.Basic+    TypeStructure.Prelude.Data+    TypeStructure.Prelude.Transformers+    TypeStructure.Prelude.TH+  exposed-modules:+    TypeStructure+  build-depends:+    -- data:+    time,+    vector,+    array,+    bytestring,+    text,+    hashable,+    unordered-containers,+    containers,+    -- control:+    transformers,+    mtl,+    -- debugging:+    loch-th == 0.2.*,+    placeholders == 0.1.*,+    -- template-haskell:+    th-instance-reification > 0.1.0 && < 0.2,+    template-haskell,+    -- general:+    base >= 4.5 && < 5+  default-extensions:+    Arrows+    BangPatterns+    ConstraintKinds+    DataKinds+    DefaultSignatures+    DeriveDataTypeable+    DeriveGeneric+    EmptyDataDecls+    FlexibleContexts+    FlexibleInstances+    FunctionalDependencies+    GADTs+    GeneralizedNewtypeDeriving+    ImpredicativeTypes+    LambdaCase+    LiberalTypeSynonyms+    MultiParamTypeClasses+    MultiWayIf+    NoImplicitPrelude+    NoMonomorphismRestriction+    OverloadedStrings+    PatternGuards+    QuasiQuotes+    RankNTypes+    RecordWildCards+    ScopedTypeVariables+    StandaloneDeriving+    TemplateHaskell+    TupleSections+    TypeFamilies+    TypeOperators+  default-language:+    Haskell2010+++test-suite type-structure-htf-test-suite+  type:             +    exitcode-stdio-1.0+  hs-source-dirs:   +    src+  main-is:          +    HTFTestSuite.hs+  ghc-options:+    -threaded+    "-with-rtsopts=-N"+  build-depends:+    -- testing:+    quickcheck-instances,+    QuickCheck-GenT == 0.1.*,+    QuickCheck,+    HUnit,+    HTF == 0.11.*,+    -- data:+    time,+    vector,+    array,+    bytestring,+    text,+    hashable,+    unordered-containers,+    containers,+    -- control:+    transformers,+    mtl,+    -- debugging:+    loch-th == 0.2.*,+    placeholders == 0.1.*,+    -- template-haskell:+    th-instance-reification > 0.1.0 && < 0.2,+    template-haskell,+    -- general:+    base >= 4.5 && < 5+  default-extensions:+    Arrows+    BangPatterns+    ConstraintKinds+    DataKinds+    DefaultSignatures+    DeriveDataTypeable+    DeriveGeneric+    EmptyDataDecls+    FlexibleContexts+    FlexibleInstances+    FunctionalDependencies+    GADTs+    GeneralizedNewtypeDeriving+    ImpredicativeTypes+    LambdaCase+    LiberalTypeSynonyms+    MultiParamTypeClasses+    MultiWayIf+    NoImplicitPrelude+    NoMonomorphismRestriction+    OverloadedStrings+    PatternGuards+    QuasiQuotes+    RankNTypes+    RecordWildCards+    ScopedTypeVariables+    StandaloneDeriving+    TemplateHaskell+    TupleSections+    TypeFamilies+    TypeOperators+  default-language:+    Haskell2010+