diff --git a/Impl.hs b/Impl.hs
new file mode 100644
--- /dev/null
+++ b/Impl.hs
@@ -0,0 +1,28 @@
+{-# OPTIONS_HADDOCK show-extensions #-}
+-- | This small but extensible framework facilitates defining complex defaulting rules that are not handled by @DefaultSignatures@, and reducing the overhead of giving instances to new datatypes by generating superclasses. One reason we might want this is when a superclass wants to be given a default by two different subclasses (ex: @Bifunctor@ and @Profunctor@ both could generate @Functor@ instances). See the @example@ internal library for how to implement instances of 'Impl'.
+module Impl (Impl(..),NamedMethods
+  -- * Reexports
+  ,type (:->),TypeQ,(!) ,type (:!), NamedF(Arg), arg
+  ) where
+import Language.Haskell.TH
+import Named hiding (Name)
+import GHC.TypeLits (Symbol)
+import Impl.Utils
+ 
+class Impl c where
+  type Methods c :: [Symbol]
+  -- | Instantiate the implementing class along with all its superclasses
+  -- Ex: 
+  --
+  -- > impl @Monad [t|[]|]
+  -- >   ! #return [|\x -> [x]|]
+  -- >   ! #bind   [|flip concatMap|]
+  impl :: TypeQ -> NamedMethods c :-> DecsQ
+
+-- | 
+type family NamedExpQ ss where
+  NamedExpQ '[] = '[]
+  NamedExpQ (s ': ss) = (s :! ExpQ) ': NamedExpQ ss
+
+-- | "Named" TH 'Exp's for the class method implementations
+type NamedMethods c = NamedExpQ (Methods c)
diff --git a/Impl/Utils.hs b/Impl/Utils.hs
new file mode 100644
--- /dev/null
+++ b/Impl/Utils.hs
@@ -0,0 +1,26 @@
+module Impl.Utils where
+import Language.Haskell.TH
+
+typeList :: [Type] -> Type
+typeList = foldr (\t -> AppT (AppT PromotedConsT t)) PromotedNilT
+
+-- | Converts a variable number of arguments into curried form. Ex:
+--
+--  >>> :!kind '[Int,String,Double] :-> IO ()
+--  Int -> String -> Double -> IO ()
+infixr 0 :->
+type family as :-> r where
+  (a ': as) :-> r = a -> as :-> r
+  '[] :-> r = r
+
+methodsFor :: Name -- ^ Typeclass name
+           -> TypeQ -- ^ @ :: [Symbol]@
+ 
+-- | Retrieve the method names of a typeclass as a typelevel list of @Symbol@s.
+-- A good default for instantiating the 'Methods' type,
+-- which is robust against changing method names
+methodsFor n = do
+  ClassI (ClassD _ _ _ _ (map sigSym -> ss)) _ <- reify n
+  return (typeList ss )
+  where sigSym (SigD (nameBase -> s) _) = LitT (StrTyLit s)
+
diff --git a/example/Monad/Foo.hs b/example/Monad/Foo.hs
new file mode 100644
--- /dev/null
+++ b/example/Monad/Foo.hs
@@ -0,0 +1,8 @@
+module Monad.Foo where
+import Monad.Impl
+
+data Foo a = Foo a
+
+impl @Monad [t|Foo|]
+  ! #return [|Foo|]
+  ! #bind [|\(Foo a) f -> f a|]
diff --git a/example/Monad/Impl.hs b/example/Monad/Impl.hs
new file mode 100644
--- /dev/null
+++ b/example/Monad/Impl.hs
@@ -0,0 +1,15 @@
+module Monad.Impl (module X) where
+import Impl as X
+
+instance Impl Monad where
+  type Methods Monad = '["return","bind"]
+  impl m (Arg return) (Arg bind) = [d|
+    instance Monad $m where
+      return = $return
+      (>>=) = $bind
+    instance Applicative $m where 
+      pure = $return
+      mf <*> ma = $bind mf $ \f -> $bind ma $ \a -> $return (f a)
+    instance Functor $m where
+      fmap f ma = $bind ma $ \a -> $return (f a)
+   |]
diff --git a/impl.cabal b/impl.cabal
new file mode 100644
--- /dev/null
+++ b/impl.cabal
@@ -0,0 +1,41 @@
+cabal-version: 2.2
+name: impl
+homepage: https://github.com/exordium/impl#readme
+version: 0.1.0.0
+category: Development, Template Haskell
+synopsis: Framework for defaulting superclasses
+stability: cursed
+bug-reports: https://github.com/exordium/impl/issues
+author: Dai
+maintainer: daig@sodality.cc
+copyright: 2018 Sodality
+license: MIT
+
+source-repository head
+  type: git
+  location: https://github.com/exordium/impl
+
+common x
+  default-language: Haskell2010
+  default-extensions: TypeFamilies, ViewPatterns, DataKinds, TypeOperators,  AllowAmbiguousTypes, TypeApplications, OverloadedLabels, TemplateHaskell, PolyKinds
+  build-depends: base ^>= 4.12.0.0
+
+library
+  import: x
+  exposed-modules: Impl
+  other-modules: Impl.Utils
+  build-depends: template-haskell ^>= 2.14.0.0
+               , named ^>= 0.2.0.0
+
+Flag DumpExample
+  Description: Show generated TH in example
+  Default: False
+  Manual: True
+
+library example
+  import: x
+  hs-source-dirs: example
+  exposed-modules: Monad.Impl, Monad.Foo
+  if flag(DumpExample)
+    ghc-options: -ddump-splices -dsuppress-uniques
+  build-depends: impl
