diff --git a/rebindable.cabal b/rebindable.cabal
new file mode 100644
--- /dev/null
+++ b/rebindable.cabal
@@ -0,0 +1,24 @@
+-- This file has been generated from package.yaml by hpack version 0.14.1.
+--
+-- see: https://github.com/sol/hpack
+
+name:           rebindable
+version:        0.1.0
+synopsis:       A library to facilitate rebinding of Haskell syntax
+maintainer:     Sean Lee <freshdried@gmail.com>
+license:        MIT
+build-type:     Simple
+cabal-version:  >= 1.10
+
+library
+  hs-source-dirs:
+      src
+  ghc-options: -Wall
+  build-depends:
+      base >= 4.9 && < 5
+    , data-default-class
+    , indexed
+  exposed-modules:
+      Language.Haskell.Rebindable
+      Language.Haskell.Rebindable.Do
+  default-language: Haskell2010
diff --git a/src/Language/Haskell/Rebindable.hs b/src/Language/Haskell/Rebindable.hs
new file mode 100644
--- /dev/null
+++ b/src/Language/Haskell/Rebindable.hs
@@ -0,0 +1,5 @@
+module Language.Haskell.Rebindable (
+  module Language.Haskell.Rebindable.Do,
+) where
+
+import Language.Haskell.Rebindable.Do
diff --git a/src/Language/Haskell/Rebindable/Do.hs b/src/Language/Haskell/Rebindable/Do.hs
new file mode 100644
--- /dev/null
+++ b/src/Language/Haskell/Rebindable/Do.hs
@@ -0,0 +1,36 @@
+{-# LANGUAGE DuplicateRecordFields #-}
+{-# LANGUAGE RankNTypes #-}
+{-# LANGUAGE GADTs #-}
+
+module Language.Haskell.Rebindable.Do where
+
+import           Data.Default.Class
+import           Prelude hiding ((>>), (>>=), return, Monad)
+import qualified Control.Monad.Indexed as P
+import qualified Prelude as P
+
+data Monad = Monad
+  { return :: forall a m. (P.Monad m) => a -> m a
+  , (>>=) :: forall a b m. (P.Monad m) =>  m a -> (a -> m b) -> m b
+  , (>>) :: forall a b m. (P.Monad m) =>  m a -> m b -> m b
+  }
+
+data IxMonad = IxMonad
+  { return :: forall a i m. (P.IxMonad m) =>  a -> m i i a
+  , (>>=) :: forall a b i j k m. (P.IxMonad m) => m i j a -> (a -> m j k b) -> m i k b
+  , (>>) :: forall a b i j k m. (P.IxMonad m) => m i j a -> m j k b -> m i k b
+  }
+
+instance Default Monad where
+  def = Monad
+    { return = P.return
+    , (>>=) = (P.>>=)
+    , (>>) = (P.>>)
+    }
+
+instance Default IxMonad where
+  def = IxMonad
+    { return = P.ireturn
+    , (>>=) = (P.>>>=)
+    , (>>) = \a b -> a P.>>>= (\_ -> b)
+    }
