diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,4 @@
+# Changelog
+
+## v0 2020-06-20
+  - First release
diff --git a/Data/DeriveLiftedInstances.hs b/Data/DeriveLiftedInstances.hs
new file mode 100644
--- /dev/null
+++ b/Data/DeriveLiftedInstances.hs
@@ -0,0 +1,118 @@
+{-# LANGUAGE ViewPatterns #-}
+{-# LANGUAGE TemplateHaskell #-}
+{-# OPTIONS_GHC -fno-warn-orphans #-}
+-----------------------------------------------------------------------------
+-- |
+-- Module      :  Data.DeriveLiftedInstances
+-- Copyright   :  (c) Sjoerd Visscher 2020
+--
+-- Maintainer  :  sjoerd@w3future.com
+-- Stability   :  experimental
+-- Portability :  non-portable
+-----------------------------------------------------------------------------
+module Data.DeriveLiftedInstances (
+  -- * Deriving instances
+  deriveInstance,
+  -- * Derivators for any class
+  idDeriv, newtypeDeriv, isoDeriv,
+  -- * Derivators for algebraic classes
+  -- $algebraic-classes
+  apDeriv, tupleDeriv, unitDeriv,
+  showDeriv, ShowsPrec(..),
+  -- * Creating derivators
+  Derivator(..)
+) where
+
+import Language.Haskell.TH
+import Data.DeriveLiftedInstances.Internal
+import Control.Arrow ((***))
+import Control.Applicative (liftA2)
+
+-- $algebraic-classes
+-- Algebraic classes are type classes where all the methods return a value of the same type, which is also the class parameter.
+-- Examples from base are `Num` and `Monoid`.
+
+-- | Given how to derive an instance for @a@, `apDeriv` creates a `Derivator` for @f a@,
+-- when @f@ is an instance of `Applicative`. Example:
+--
+-- @
+-- `deriveInstance` (`apDeriv` `idDeriv`) [t| forall a. `Num` a => `Num` [a] |]
+--
+-- > [2, 3] `*` [5, 10]
+-- [10, 20, 15, 30]
+-- @
+apDeriv :: Derivator -> Derivator
+apDeriv deriv = deriv {
+  res = \v -> [| fmap (\w -> $(res deriv [| w |])) $v |],
+  op  = \nm o -> [| pure $(op deriv nm o) |],
+  arg = \ty e -> [| pure $(arg deriv ty e) |],
+  var = \fold v ->
+    [| fmap (\w -> $(var deriv fold [| w |])) ($(fold [| traverse |] [| id |]) $v) |],
+  ap  = \f a -> [| liftA2 (\g b -> $(ap deriv [| g |] [| b |])) $f $a |]
+}
+
+-- | Given how to derive an instance for @a@ and @b@, `tupleDeriv` creates a `Derivator` for @(a, b)@.
+--
+-- @
+-- `deriveInstance` (`tupleDeriv` `idDeriv` `idDeriv`) [t| forall a b. (`Num` a, `Num` b) => `Num` (a, b) |]
+--
+-- > (2, 3) `*` (5, 10)
+-- (10, 30)
+-- @
+tupleDeriv :: Derivator -> Derivator -> Derivator
+tupleDeriv l r = idDeriv {
+  res = \e -> [| ((\w -> $(res l [| w |])) *** (\w -> $(res r [| w |]))) $e |],
+  op  = \nm o -> [| ($(op l nm o), $(op r nm o)) |],
+  arg = \ty e -> [| ($(arg l ty e), $(arg r ty e)) |],
+  var = \fold v ->
+    [| ( $(var l fold [| $(fold [| fmap |] [| fst |]) $v |])
+       , $(var r fold [| $(fold [| fmap |] [| snd |]) $v |])
+       ) |],
+  ap  = \f a  -> [| case ($f, $a) of ((g, h), (b, c)) -> ($(ap l [| g |] [| b |]), $(ap r [| h |] [| c |])) |]
+}
+
+-- | A `Derivator` for @()@.
+unitDeriv :: Derivator
+unitDeriv = idDeriv {
+  op = \_ _ -> [| () |],
+  ap = const
+}
+
+-- | Given how to derive an instance for @a@, and the names of a newtype wrapper around @a@,
+-- `newtypeDeriv` creates a `Derivator` for that newtype. Example:
+--
+-- @
+-- newtype Ap f a = Ap { getAp :: f a } deriving Show
+-- `deriveInstance` (`newtypeDeriv` 'Ap 'getAp `idDeriv`) [t| forall f. `Functor` f => `Functor` (Ap f) |]
+--
+-- > `fmap` (+1) (Ap [1,2,3])
+-- Ap {getAp = [2,3,4]}
+-- @
+newtypeDeriv :: Name -> Name -> Derivator -> Derivator
+newtypeDeriv mk un = isoDeriv (pure $ ConE mk) (pure $ VarE un)
+
+-- | Given how to derive an instance for @a@, and two functions of type @a `->` b@ and @b `->` a@,
+-- `isoDeriv` creates a `Derivator` for @b@. (Note that the 2 functions don't have to form
+-- an isomorphism, but if they don't, the new instance can break the class laws.) Example:
+--
+-- @
+-- newtype X = X { unX :: `Int` } deriving `Show`
+-- mkX :: `Int` -> X
+-- mkX i = X (`mod` i 10)
+-- `deriveInstance` (isoDeriv [| mkX |] [| unX |] `idDeriv`) [t| `Num` X |]
+--
+-- > mkX 4 `^` 2
+-- X {unX = 6}
+-- @
+isoDeriv :: Q Exp -> Q Exp -> Derivator -> Derivator
+isoDeriv mk un deriv = deriv {
+  res = \v -> [| $mk $(res deriv v) |],
+  var = \fold v -> var deriv fold [| $(fold [| fmap |] un) $v |]
+}
+
+deriveInstance showDeriv [t| Bounded ShowsPrec |]
+deriveInstance showDeriv [t| Num ShowsPrec |]
+deriveInstance showDeriv [t| Fractional ShowsPrec |]
+deriveInstance showDeriv [t| Floating ShowsPrec |]
+deriveInstance showDeriv [t| Semigroup ShowsPrec |]
+deriveInstance showDeriv [t| Monoid ShowsPrec |]
diff --git a/Data/DeriveLiftedInstances/Internal.hs b/Data/DeriveLiftedInstances/Internal.hs
new file mode 100644
--- /dev/null
+++ b/Data/DeriveLiftedInstances/Internal.hs
@@ -0,0 +1,186 @@
+{-# LANGUAGE DeriveLift #-}
+{-# LANGUAGE LambdaCase #-}
+{-# LANGUAGE TupleSections #-}
+{-# LANGUAGE TemplateHaskell #-}
+{-# LANGUAGE RecordWildCards #-}
+{-# LANGUAGE StandaloneDeriving #-}
+{-# OPTIONS_GHC -fno-warn-orphans #-}
+-----------------------------------------------------------------------------
+-- |
+-- Module      :  Data.DeriveLiftedInstances.Internal
+-- Copyright   :  (c) Sjoerd Visscher 2020
+--
+-- Maintainer  :  sjoerd@w3future.com
+-- Stability   :  experimental
+-- Portability :  non-portable
+-----------------------------------------------------------------------------
+module Data.DeriveLiftedInstances.Internal where
+
+import Language.Haskell.TH
+import Language.Haskell.TH.Syntax (Lift)
+import Data.Char (isAlpha)
+import Data.Data (Data, gmapQl, cast)
+import Data.Maybe (fromMaybe, catMaybes)
+import Data.Traversable (for)
+
+
+-- | To write your own `Derivator` you need to show how each part of a method gets lifted.
+-- For example, when deriving an instance for type @a@ of the following methods:
+--
+-- @
+-- meth0 :: a
+-- meth1 :: Int -> a
+-- meth2 :: a -> Either Bool a -> Int
+-- meth3 :: Maybe [a] -> a
+-- @
+--
+-- the resulting template haskell declarations are (pseudo code):
+--
+-- @
+-- meth0 = $res ($op "meth0" meth0)
+-- meth1 a = $res (($op "meth1" meth1) `$ap` ($arg Int a))
+-- meth2 v0 v1 = (($op "meth2" meth2) `$ap` ($var fold0 v0)) `$ap` ($var fold1 v1)
+--   where
+--     fold0 _ f = f
+--     fold1 map f = [| $map $f |]
+-- meth3 v2 = $res (($op "meth2" meth2) `$ap` ($var fold2 v2))
+--   where
+--     fold2 map f = [| $map ($map $f) |]
+-- @
+data Derivator = Derivator {
+  res :: Q Exp -> Q Exp, -- ^ Convert the result of the method
+  op  :: Name -> Q Exp -> Q Exp, -- ^ Convert the method (still unapplied to any arguments)
+  arg :: Type -> Q Exp -> Q Exp, -- ^ Convert an argument
+  var :: (Q Exp -> Q Exp -> Q Exp) -> Q Exp -> Q Exp, -- ^ Convert a variable
+  ap  :: Q Exp -> Q Exp -> Q Exp -- ^ Apply an argument or variable to the method
+}
+
+varExp :: Name -> Q Exp
+varExp = pure . VarE
+
+varPat :: Name -> Q Pat
+varPat = pure . VarP
+
+-- | The identity `Derivator`. Not useful on its own, but often used as input for other `Derivator`s.
+idDeriv :: Derivator
+idDeriv = Derivator {
+  res  = id,
+  op   = const id,
+  arg  = const id,
+  var  = const id,
+  ap   = \f a -> [| $f $a |]
+}
+
+-- | Derive the instance with the given `Derivator` and the given instance head.
+--
+-- The instance head can be passed as a template haskell type quotation, for example:
+--
+-- @
+-- {-\# LANGUAGE TemplateHaskell #-}
+-- [t| `Num` `ShowsPrec` |]
+-- [t| forall a. `Num` a => `Num` [a] |]
+-- [t| forall a b. (`Num` a, `Num` b) => `Num` (a, b) |]
+-- @
+deriveInstance :: Derivator -> Q Type -> Q [Dec]
+deriveInstance deriv qtyp = do
+  typ <- qtyp
+  case typ of
+    ForallT _ ctx (AppT (ConT className) typeName) ->
+      deriveInstance' deriv ctx className typeName
+    AppT (ConT className) typeName ->
+      deriveInstance' deriv [] className typeName
+    _ -> fail $ "No support for type: " ++ show typ
+
+deriveInstance' :: Derivator -> Cxt -> Name -> Type -> Q [Dec]
+deriveInstance' deriv ctx className typeName = do
+  ClassI (ClassD _ _ [KindedTV tvn _] _ decs) _ <- reify className
+  impl <- for decs $ \case
+    SigD nm tp -> do
+      dec <- reify nm
+      case dec of
+        ClassOpI{} -> do
+          (argNames, body) <- buildOperation deriv tvn tp (op deriv nm (varExp nm))
+          let args = map (\argName -> if contains argName body then VarP argName else WildP) argNames
+          pure $ Just $ FunD nm [Clause args (NormalB body) []]
+        _ -> fail $ "No support for declaration: " ++ show dec
+    _ -> pure Nothing
+  pure [InstanceD Nothing ctx (AppT (ConT className) typeName) $ catMaybes impl]
+
+buildOperation :: Derivator -> Name -> Type -> Q Exp -> Q ([Name], Exp)
+buildOperation d nm (AppT (AppT ArrowT h) t) e | hasVar nm h = do
+  varNm <- newName "var"
+  (args, rhs) <- buildOperation d nm t (ap d e (var d (buildArgument nm h) (varExp varNm)))
+  pure (varNm : args, rhs)
+buildOperation d nm (AppT (AppT ArrowT h) t) e = do
+  varNm <- newName "arg"
+  (args, rhs) <- buildOperation d nm t (ap d e (arg d h (varExp varNm)))
+  pure (varNm : args, rhs)
+buildOperation d nm (ForallT _ _ t) e = buildOperation d nm t e
+buildOperation d nm t e | isVar nm t = ([],) <$> res d e
+                        | otherwise = ([],) <$> e
+
+buildArgument :: Name -> Type -> Q Exp -> Q Exp -> Q Exp
+buildArgument nm (AppT h _) _ var | isVar nm h = var
+buildArgument nm (AppT _ h) over var = [| $over $(buildArgument nm h over var) |]
+buildArgument _ _ _ var = var
+
+isVar :: Name -> Type -> Bool
+isVar nm (VarT nm') = nm == nm'
+isVar nm (AppT h _) = isVar nm h
+isVar _ _ = False
+
+hasVar :: Name -> Type -> Bool
+hasVar nm (VarT nm') = nm == nm'
+hasVar nm (AppT f a) = isVar nm f || hasVar nm a
+hasVar _ _ = False
+
+tvName :: TyVarBndr -> Name
+tvName (PlainTV nm) = nm
+tvName (KindedTV nm _) = nm
+
+contains :: Data d => Name -> d -> Bool
+contains nm = gmapQl (||) False (\d -> maybe (contains nm d) (== nm) $ cast d)
+
+
+deriving instance Lift Fixity
+deriving instance Lift FixityDirection
+
+-- | Helper for showing infix expressions
+data ShowsPrec = ShowsPrec (Int -> String -> String) | ShowOp2 Fixity (Int -> String -> String) | ShowOp1 Fixity (Int -> String -> String)
+instance Show ShowsPrec where
+  showsPrec d (ShowsPrec f) = f d
+  showsPrec d (ShowOp2 (Fixity p _) f) = showParen (d > p) $ f 0
+  showsPrec _ (ShowOp1 _ f) = showParen True $ f 0
+
+showAp :: ShowsPrec -> ShowsPrec -> ShowsPrec
+showAp (ShowsPrec f) (ShowsPrec g) = ShowsPrec $ \d -> showParen (d > 10) $ f 10 . showChar ' ' . g 11
+showAp (ShowOp2 fx@(Fixity p i) f) (ShowsPrec g) = ShowOp1 fx $ \_ -> g (p + fromEnum (i /= InfixL)) . showChar ' ' . f 0
+showAp (ShowOp1 (Fixity p i) f) (ShowsPrec g) = ShowsPrec $ \d -> showParen (d > p) (f 0 . showChar ' ' . g (p + fromEnum (i /= InfixR)))
+showAp _ _ = error "Unexpected use of showAp"
+
+-- | Derive instances for `ShowsPrec`. Example:
+--
+-- @
+-- `deriveInstance` `showDeriv` [t| `Num` `ShowsPrec` |]
+--
+-- > `show` ((6 `*` 7) `^` 2 :: `ShowsPrec`)
+-- "fromInteger 6 * fromInteger 7 * (fromInteger 6 * fromInteger 7)"
+-- @
+showDeriv :: Derivator
+showDeriv = idDeriv {
+  op = \nm _ -> let name = nameBase nm in if isOperator name
+    then do
+      fx <- fromMaybe defaultFixity <$> reifyFixity nm
+      [| ShowOp2 fx $ const $ showString $(pure . LitE . StringL $ name) |]
+    else
+      [| ShowsPrec  $ const $ showString $(pure . LitE . StringL $ name) |],
+  arg = \case
+    (VarT _) -> const [| ShowsPrec $ const (showString "#Unshowable#") |]
+    _ -> \v -> [| ShowsPrec $ flip showsPrec $v |],
+  var = \_ v ->  [| ShowsPrec $ flip showsPrec $v |],
+  ap  = \f a -> [| showAp $f $a |]
+}
+
+isOperator :: String -> Bool
+isOperator (c:_) = not (isAlpha c) && c /= '_'
+isOperator _ = False
diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,201 @@
+Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
diff --git a/README.md b/README.md
new file mode 100644
--- /dev/null
+++ b/README.md
@@ -0,0 +1,1 @@
+# derive-lifted-instances
diff --git a/derive-lifted-instances.cabal b/derive-lifted-instances.cabal
new file mode 100644
--- /dev/null
+++ b/derive-lifted-instances.cabal
@@ -0,0 +1,34 @@
+name:                derive-lifted-instances
+version:             0
+synopsis:            Derive class instances though various kinds of lifting
+description:         Helper functions to use Template Haskell for generating class instances.
+homepage:            https://github.com/sjoerdvisscher/derive-lifted-instances
+bug-reports:         https://github.com/sjoerdvisscher/derive-lifted-instances/issues
+license:             Apache-2.0
+license-file:        LICENSE
+author:              Sjoerd Visscher
+maintainer:          sjoerd@w3future.com
+category:            Data, Generics, Development
+build-type:          Simple
+cabal-version:       2.0
+
+extra-source-files:
+  examples/*.hs
+  README.md
+  CHANGELOG.md
+
+library
+  exposed-modules:
+    Data.DeriveLiftedInstances
+    Data.DeriveLiftedInstances.Internal
+
+  build-depends:
+      base >= 4.13 && < 4.15
+    , template-haskell >= 2.15 && < 2.17
+
+  default-language:
+    Haskell2010
+
+source-repository head
+  type:     git
+  location: git://github.com/sjoerdvisscher/derive-lifted-instances.git
diff --git a/examples/Test.hs b/examples/Test.hs
new file mode 100644
--- /dev/null
+++ b/examples/Test.hs
@@ -0,0 +1,56 @@
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE RankNTypes #-}
+{-# LANGUAGE TemplateHaskell #-}
+module Test where
+
+import Data.DeriveLiftedInstances
+import Data.Functor.Identity
+
+class Test a where
+  op0 :: a
+  op1 :: Int -> [a] -> a
+  op2 :: [[a]] -> a
+
+instance Test Int where
+  op0 = 1
+  op1 i is = i + sum is
+  op2 = sum . fmap sum
+
+newtype X = X { unX :: Int } deriving Show
+mkX :: Int -> X
+mkX = X . (`mod` 10)
+deriveInstance (isoDeriv [| mkX |] [| unX |] idDeriv) [t| Test X |]
+deriveInstance (isoDeriv [| mkX |] [| unX |] idDeriv) [t| Eq X |]
+deriveInstance (isoDeriv [| mkX |] [| unX |] idDeriv) [t| Ord X |]
+deriveInstance (isoDeriv [| mkX |] [| unX |] idDeriv) [t| Num X |]
+
+deriveInstance showDeriv [t| Test ShowsPrec |]
+deriveInstance unitDeriv [t| Test () |]
+deriveInstance (apDeriv idDeriv) [t| forall a. Test a => Test [a] |]
+deriveInstance (tupleDeriv idDeriv idDeriv) [t| forall a b. (Test a, Test b) => Test (a, b) |]
+-- deriveInstance (newtypeDeriv 'Identity 'runIdentity idDeriv) [t| forall a. Test a => Test (Identity a) |]
+
+newtype Ap f a = Ap { getAp :: f a } deriving Show
+deriveInstance (newtypeDeriv 'Ap 'getAp (apDeriv idDeriv)) [t| forall f a. (Applicative f, Test a) => Test (Ap f a) |]
+
+deriveInstance (newtypeDeriv 'Identity 'runIdentity (newtypeDeriv 'Ap 'getAp (apDeriv idDeriv))) [t| forall f a. (Applicative f, Test a) => Test (Identity (Ap f a)) |]
+
+newtype Id a = Id { runId :: a }
+deriveInstance (apDeriv (apDeriv (newtypeDeriv 'Id 'runId idDeriv))) [t| forall a. Test a => Test (() -> Identity (Id a)) |]
+deriveInstance (apDeriv (tupleDeriv idDeriv idDeriv)) [t| forall a b. (Test a, Test b) => Test (() -> (a, b)) |]
+deriveInstance (tupleDeriv (apDeriv idDeriv) (newtypeDeriv 'Id 'runId idDeriv)) [t| forall a b. (Test a, Test b) => Test (() -> a, Id b) |]
+
+class Test1 f where
+  hop0 :: f a
+  hop0' :: f Int
+  hop1 :: Int -> f Int -> f Int
+
+instance Test1 [] where
+  hop0 = []
+  hop0' = [1]
+  hop1 i = map (+ i)
+
+deriveInstance (newtypeDeriv 'Ap 'getAp idDeriv) [t| forall f. Test1 f => Test1 (Ap f) |]
+deriveInstance (newtypeDeriv 'Ap 'getAp idDeriv) [t| forall f. Functor f => Functor (Ap f) |]
+deriveInstance (newtypeDeriv 'Ap 'getAp idDeriv) [t| forall f. Applicative f => Applicative (Ap f) |]
+deriveInstance (newtypeDeriv 'Ap 'getAp idDeriv) [t| forall f. Monad f => Monad (Ap f) |]
