diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,30 @@
+Copyright Aaron Friel (c) 2017
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+
+    * 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.
+
+    * Neither the name of Aaron Friel nor the names of other
+      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.
diff --git a/README.md b/README.md
new file mode 100644
--- /dev/null
+++ b/README.md
@@ -0,0 +1,33 @@
+# graphted
+
+Indexed type classes that track operations performed on them.
+The index parameter then models control flow.
+
+Implements graph-indexed type classes for:
+
+- [X] `Pointed`
+- [X] `Functor`
+- [X] `Applicative`
+- [ ] `Alternative`
+  - TODO: `Alternative` vs `MonadOr`?
+- [X] `Monad`
+- [X] `MonadFail`
+- [X] `MonadZero`
+- [X] `MonadOr`
+- [X] `MonadPlus`
+
+May implement in the future, or may not make sense.
+
+(Essentially: [`category-extras`](http://hackage.haskell.org/package/category-extras).)
+
+- [ ] `Category`
+  - [ ] `Kleisli`
+  - [ ] `Cokleisli`
+- [ ] `Arrow`
+  - [ ] `ArrowZero`
+  - [ ] `ArrowPlus`
+- [ ] `Apply`, `Bind`, `Extend` a la [`semigroupoids`](http://hackage.haskell.org/package/semigroupoids)
+- [ ] `Copointed`, `Comonad`
+- [ ] `Foldable` (`Foldable1`)
+- [ ] `Traversable` (`Traversable1`)
+- [ ] `Traversable` (`Traversable1`)
diff --git a/Setup.hs b/Setup.hs
new file mode 100644
--- /dev/null
+++ b/Setup.hs
@@ -0,0 +1,2 @@
+import Distribution.Simple
+main = defaultMain
diff --git a/graphted.cabal b/graphted.cabal
new file mode 100644
--- /dev/null
+++ b/graphted.cabal
@@ -0,0 +1,35 @@
+name:                graphted
+version:             0.1.0.0
+synopsis:    Graph indexed monads.
+-- description: TODO
+homepage:            https://github.com/aaronfriel/graphted#readme
+license:             BSD3
+license-file:        LICENSE
+author:              Aaron Friel
+maintainer:          mayreply@aaronfriel.com
+copyright:           BSD3
+category:            Web
+build-type:          Simple
+extra-source-files:  README.md
+cabal-version:       >=1.10
+
+library
+  hs-source-dirs:      src
+  exposed-modules:     Control.Graphted
+                     , Control.Graphted.Class
+                     , Control.Applicative.Graph
+                     , Control.Monad.Graph
+                     , Control.MonadFail.Graph
+                     , Control.MonadZero.Graph
+                     , Control.MonadOr.Graph
+                     , Control.MonadPlus.Graph
+                     , Data.Functor.Graph
+                     , Data.Pointed.Graph
+                     , Data.GWrapped
+                     , Prelude.Graphted
+  build-depends:       base >= 4.7 && < 5
+  default-language:    Haskell2010
+
+source-repository head
+  type:     git
+  location: https://github.com/aaronfriel/graphted
diff --git a/src/Control/Applicative/Graph.hs b/src/Control/Applicative/Graph.hs
new file mode 100644
--- /dev/null
+++ b/src/Control/Applicative/Graph.hs
@@ -0,0 +1,54 @@
+{- |
+Module      :  Control.Applicative.Graph
+Description :  Graph indexed applicative functors
+Copyright   :  (c) Aaron Friel
+License     :  BSD-3
+
+Maintainer  :  Aaron Friel <mayreply@aaronfriel.com>
+Stability   :  unstable
+Portability :  portable
+
+-}
+
+{-# LANGUAGE DefaultSignatures     #-}
+{-# LANGUAGE FlexibleContexts      #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE Polypinds             #-}
+{-# LANGUAGE TypeFamilies          #-}
+
+-- For the default Apply, Then, and But instances.
+{-# LANGUAGE UndecidableInstances  #-}
+
+module Control.Applicative.Graph where
+
+import Control.Graphted.Class
+
+import Data.Functor.Graph
+import Data.Pointed.Graph
+
+class (GFunctor f, GPointed f) => GApplicative (f :: p -> * -> *) where
+    type family Apply f (i :: p) (j :: p) :: p
+    type instance Apply f i j = Combine f i j
+
+    type family Then f (i :: p) (j :: p) :: p
+    type instance Then f i j = Apply f (Fconst f i) j
+
+    type family But f (i :: p) (j :: p) :: p
+    type instance But f i j = Apply f (Apply f (Pure f) i) j
+
+    -- <*>
+    gap :: Inv f i j => f i (a -> b) -> f j a -> f (Apply f i j) b
+
+    -- *>
+    {-# INLINE gthen #-}
+    gthen :: Inv f i j => f i a -> f j b -> f (Then f i j) b
+    default gthen :: (Apply f (Fconst f i) j ~ Then f i j, Inv f (Fconst f i) j)
+                  => f i a -> f j b -> f (Then f i j) b
+    gthen a b = (id `gconst` a) `gap` b
+
+    -- <*
+    {-# INLINE gbut #-}
+    gbut :: Inv f i j => f i a -> f j b -> f (But f i j) a
+    default gbut :: (Apply f (Apply f (Pure f) i) j ~ But f i j, Inv f (Pure f) i, Inv f (Apply f (Pure f) i) j)
+                 => f i a -> f j b -> f (But f i j) a
+    gbut a b = gpoint const `gap` a `gap` b
diff --git a/src/Control/Graphted.hs b/src/Control/Graphted.hs
new file mode 100644
--- /dev/null
+++ b/src/Control/Graphted.hs
@@ -0,0 +1,39 @@
+{- |
+Module      :  Control.Graphted
+Description :  Graph indexed types
+Copyright   :  (c) Aaron Friel
+License     :  BSD-3
+
+Maintainer  :  Aaron Friel <mayreply@aaronfriel.com>
+Stability   :  unstable | experimental | provisional | stable | frozen
+Portability :  portable | non-portable (<reason>)
+
+-}
+
+module Control.Graphted (
+    module Control.Graphted.Class,
+
+    module Control.Applicative.Graph,
+    module Control.Monad.Graph,
+
+    module Control.MonadFail.Graph,
+    module Control.MonadZero.Graph,
+    module Control.MonadPlus.Graph,
+    module Control.MonadOr.Graph,
+    
+    module Data.Pointed.Graph,
+    module Data.Functor.Graph
+    )   where
+
+import Control.Graphted.Class
+
+import Control.Applicative.Graph
+import Control.Monad.Graph
+
+import Control.MonadFail.Graph
+import Control.MonadZero.Graph
+import Control.MonadPlus.Graph
+import Control.MonadOr.Graph
+
+import Data.Functor.Graph
+import Data.Pointed.Graph
diff --git a/src/Control/Graphted/Class.hs b/src/Control/Graphted/Class.hs
new file mode 100644
--- /dev/null
+++ b/src/Control/Graphted/Class.hs
@@ -0,0 +1,38 @@
+{- |
+Module      :  Control.Graph.Base
+Description :  Base type class for graph indexed types.
+Copyright   :  (c) Aaron Friel
+License     :  BSD-3
+
+Maintainer  :  Aaron Friel <mayreply@aaronfriel.com>
+Stability   :  unstable
+Portability :  portable
+
+-}
+
+{-# LANGUAGE ConstraintKinds #-}
+{-# LANGUAGE PolyKinds       #-}
+{-# LANGUAGE TypeFamilies    #-}
+{-# LANGUAGE TypeInType      #-}
+
+module Control.Graphted.Class where
+
+import Data.Kind (type (*), Constraint)
+
+-- | Base class that all Graph-indexed types may implement.
+--
+class Graphted (f :: p -> * -> *) where
+    -- | The unit of our kind p.
+    type Unit f :: p
+
+    -- | An invariant on combining indexes.
+    type family Inv f (i :: p) (j :: p) :: Constraint
+    type instance Inv f i j = ()
+
+    -- | An elementary composition of indexes.
+    --
+    -- N.B.: This may be nonsensical if and only if type classes override the
+    -- default definitions of their own type families.
+    --
+    -- This exists for convenience.
+    type family Combine f (i :: p) (j :: p) :: p
diff --git a/src/Control/Monad/Graph.hs b/src/Control/Monad/Graph.hs
new file mode 100644
--- /dev/null
+++ b/src/Control/Monad/Graph.hs
@@ -0,0 +1,40 @@
+{- |
+Module      :  Control.Monad.Graph
+Description :  Graph indexed monads
+Copyright   :  (c) Aaron Friel
+License     :  BSD-3
+
+Maintainer  :  Aaron Friel <mayreply@aaronfriel.com>
+Stability   :  unstable
+Portability :  portable
+
+-}
+
+{-# LANGUAGE DefaultSignatures     #-}
+{-# LANGUAGE FlexibleContexts      #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE PolyKinds             #-}
+{-# LANGUAGE TypeFamilies          #-}
+
+-- For the default Apply, Then, and But instances.
+{-# LANGUAGE UndecidableInstances  #-}
+
+module Control.Monad.Graph where
+
+import Control.Graphted.Class
+
+import Control.Applicative.Graph
+
+class GApplicative m => GMonad (m :: p -> * -> *) where
+    type family Bind m (i :: p) (j :: p) :: p
+    type instance Bind m i j = Combine m i j
+
+    type family Join m (i :: p) (j :: p) :: p
+    type instance Join m i j = Bind m i j
+
+    gbind :: Inv m i j => m i a -> (a -> m j b) -> m (Bind m i j) b
+
+    {-# INLINE gjoin #-}
+    gjoin :: (Inv m i j) => m i (m j b) -> m (Join m i j) b
+    default gjoin :: (Bind m i j ~ Join m i j, Inv m i j) => m i (m j b) -> m (Join m i j) b
+    gjoin x = x `gbind` id
diff --git a/src/Control/MonadFail/Graph.hs b/src/Control/MonadFail/Graph.hs
new file mode 100644
--- /dev/null
+++ b/src/Control/MonadFail/Graph.hs
@@ -0,0 +1,36 @@
+{- |
+Module      :  Control.MonadFail.Graph
+Description :  Graph indexed monads with failure
+Copyright   :  (c) Aaron Friel
+License     :  BSD-3
+
+Maintainer  :  Aaron Friel <mayreply@aaronfriel.com>
+Stability   :  unstable
+Portability :  portable
+
+-}
+
+{-# LANGUAGE DefaultSignatures     #-}
+{-# LANGUAGE FlexibleContexts      #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE PolyKinds             #-}
+{-# LANGUAGE TypeFamilies          #-}
+
+-- For the default Apply, Then, and But instances.
+{-# LANGUAGE UndecidableInstances  #-}
+
+module Control.MonadFail.Graph where
+
+import Control.Graphted.Class
+
+import Control.Monad.Graph
+import Control.MonadZero.Graph
+
+class GMonad m => GMonadFail (m :: p -> * -> *) where
+    type family Fail m :: p
+    type instance Fail m = Unit m
+
+    gfail :: String -> m (Fail m) a
+
+    default gfail :: (GMonadZero m, Zero m ~ Fail m) => String -> m (Fail m) a
+    gfail _ = gzero
diff --git a/src/Control/MonadOr/Graph.hs b/src/Control/MonadOr/Graph.hs
new file mode 100644
--- /dev/null
+++ b/src/Control/MonadOr/Graph.hs
@@ -0,0 +1,32 @@
+{- |
+Module      :  Control.MonadOr.Graph
+Description :  Graph indexed monads with choice and failure
+Copyright   :  (c) Aaron Friel
+License     :  BSD-3
+
+Maintainer  :  Aaron Friel <mayreply@aaronfriel.com>
+Stability   :  unstable
+Portability :  portable
+
+-}
+
+{-# LANGUAGE DefaultSignatures     #-}
+{-# LANGUAGE FlexibleContexts      #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE PolyKinds             #-}
+{-# LANGUAGE TypeFamilies          #-}
+
+-- For the default Apply, Then, and But instances.
+{-# LANGUAGE UndecidableInstances  #-}
+
+module Control.MonadOr.Graph where
+
+import Control.Graphted.Class
+
+import Control.MonadZero.Graph
+
+class GMonadZero m => GMonadOr (m :: p -> * -> *) where
+    type family Or m (i :: p) (j :: p) :: p
+    type instance Or m i j = Combine m i j
+
+    gorelse :: m i a -> m j a -> m (Or m i j) a
diff --git a/src/Control/MonadPlus/Graph.hs b/src/Control/MonadPlus/Graph.hs
new file mode 100644
--- /dev/null
+++ b/src/Control/MonadPlus/Graph.hs
@@ -0,0 +1,32 @@
+{- |
+Module      :  Control.MonadPlus.Graph
+Description :  Graph indexed monads with choice and failure
+Copyright   :  (c) Aaron Friel
+License     :  BSD-3
+
+Maintainer  :  Aaron Friel <mayreply@aaronfriel.com>
+Stability   :  unstable
+Portability :  portable
+
+-}
+
+{-# LANGUAGE DefaultSignatures     #-}
+{-# LANGUAGE FlexibleContexts      #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE PolyKinds             #-}
+{-# LANGUAGE TypeFamilies          #-}
+
+-- For the default Apply, Then, and But instances.
+{-# LANGUAGE UndecidableInstances  #-}
+
+module Control.MonadPlus.Graph where
+
+import Control.Graphted.Class
+
+import Control.MonadZero.Graph
+
+class GMonadZero m => GMonadPlus (m :: p -> * -> *) where
+    type family Plus m (i :: p) (j :: p) :: p
+    type instance Plus m i j = Combine m i j
+
+    gplus :: m i a -> m j a -> m (Plus m i j) a
diff --git a/src/Control/MonadZero/Graph.hs b/src/Control/MonadZero/Graph.hs
new file mode 100644
--- /dev/null
+++ b/src/Control/MonadZero/Graph.hs
@@ -0,0 +1,32 @@
+{- |
+Module      :  Control.MonadZero.Graph
+Description :  Graph indexed monads with failure
+Copyright   :  (c) Aaron Friel
+License     :  BSD-3
+
+Maintainer  :  Aaron Friel <mayreply@aaronfriel.com>
+Stability   :  unstable
+Portability :  portable
+
+-}
+
+{-# LANGUAGE DefaultSignatures     #-}
+{-# LANGUAGE FlexibleContexts      #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE PolyKinds             #-}
+{-# LANGUAGE TypeFamilies          #-}
+
+-- For the default Apply, Then, and But instances.
+{-# LANGUAGE UndecidableInstances  #-}
+
+module Control.MonadZero.Graph where
+
+import Control.Graphted.Class
+
+import Control.Monad.Graph
+
+class GMonad m => GMonadZero (m :: p -> * -> *) where
+    type family Zero m :: p
+    type instance Zero m = Unit m
+
+    gzero :: m (Zero m) a
diff --git a/src/Data/Functor/Graph.hs b/src/Data/Functor/Graph.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Functor/Graph.hs
@@ -0,0 +1,33 @@
+{- |
+Module      :  Data.Functor.Graph
+Description :  Graph indexed functors
+Copyright   :  (c) Aaron Friel
+License     :  BSD-3
+
+Maintainer  :  Aaron Friel <mayreply@aaronfriel.com>
+Stability   :  unstable | experimental | provisional | stable | frozen
+Portability :  portable | non-portable (<reason>)
+
+<module description starting at first column>
+-}
+
+{-# LANGUAGE DefaultSignatures    #-}
+{-# LANGUAGE PolyKinds            #-}
+{-# LANGUAGE TypeFamilies         #-}
+{-# LANGUAGE UndecidableInstances #-}
+
+module Data.Functor.Graph where
+
+class GFunctor (f :: p -> * -> *) where
+    type family Fmap f (i :: p) :: p
+    type instance Fmap f i = i
+
+    type family Fconst f (i :: p) :: p
+    type instance Fconst f i = Fmap f i
+
+    gmap :: (a -> b) -> f i a -> f (Fmap f i) b
+
+    {-# INLINABLE gconst #-}
+    gconst :: a -> f i b -> f (Fconst f i) a
+    default gconst :: (Fconst f i ~ Fmap f i) => a -> f i b -> f (Fconst f i) a
+    gconst = gmap . const
diff --git a/src/Data/GWrapped.hs b/src/Data/GWrapped.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/GWrapped.hs
@@ -0,0 +1,67 @@
+{- |
+Module      :  Data.GWrapped
+Description :
+Copyright   :  (c) Aaron Friel
+License     :  BSD-3
+
+Maintainer  :  Aaron Friel <mayreply@aaronfriel.com>
+Stability   :  unstable
+Portability :  portable
+
+
+-}
+
+{-# LANGUAGE GADTs         #-}
+{-# LANGUAGE PolyKinds     #-}
+{-# LANGUAGE TypeFamilies  #-}
+{-# LANGUAGE TypeOperators #-}
+
+module Data.GWrapped where
+
+import Control.Graphted
+
+import Control.Applicative (Alternative (..))
+import Control.Monad (MonadPlus (..))
+import Data.Type.Equality (type (~~))
+
+-- Wrapping a non-indexed type constructor:
+newtype GWrapped (m :: * -> *) (p :: *) a = GWrapped { unGwrap :: m a }
+
+unM :: GWrapped m p a -> m a
+unM (GWrapped m) = m
+
+liftG :: m a -> GWrapped m () a
+liftG = GWrapped
+
+instance Graphted (GWrapped m) where
+    type Unit (GWrapped _) = ()
+    type Inv (GWrapped _) i j = i ~~ j
+    type Combine (GWrapped _) i j = i
+
+instance Applicative f => GPointed (GWrapped f) where
+    gpoint' = GWrapped . pure
+
+instance Functor f => GFunctor (GWrapped f) where
+    gmap f = GWrapped . fmap f . unGwrap
+    gconst f = GWrapped . ((<$) f) . unGwrap
+
+instance Applicative f => GApplicative (GWrapped f) where
+    gap   (GWrapped m) (GWrapped k) = GWrapped $ m <*> k
+    gthen (GWrapped m) (GWrapped k) = GWrapped $ m  *> k
+    gbut  (GWrapped m) (GWrapped k) = GWrapped $ m <* k
+
+instance Monad m => GMonad (GWrapped m) where
+    gbind (GWrapped m) k = GWrapped $ m >>= unM . k
+    gjoin (GWrapped m) = GWrapped $ m >>= unM
+
+instance Monad m => GMonadFail (GWrapped m) where
+    gfail = GWrapped . fail
+
+instance MonadPlus m => GMonadZero (GWrapped m) where
+    gzero = GWrapped $ mzero
+
+instance MonadPlus m => GMonadPlus (GWrapped m) where
+    gplus (GWrapped m) (GWrapped k) = GWrapped $ m `mplus` k
+
+instance (Alternative m, MonadPlus m) => GMonadOr (GWrapped m) where
+    gorelse (GWrapped m) (GWrapped k) = GWrapped $ m <|> k
diff --git a/src/Data/Pointed/Graph.hs b/src/Data/Pointed/Graph.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Pointed/Graph.hs
@@ -0,0 +1,34 @@
+{- |
+Module      :  Control.Applicative.Graph
+Description :  Graph indexed applicative functors
+Copyright   :  (c) Aaron Friel
+License     :  BSD-3
+
+Maintainer  :  Aaron Friel <mayreply@aaronfriel.com>
+Stability   :  unstable
+Portability :  portable
+
+-}
+
+{-# LANGUAGE PolyKinds            #-}
+{-# LANGUAGE ScopedTypeVariables  #-}
+{-# LANGUAGE TypeApplications     #-}
+{-# LANGUAGE TypeFamilies         #-}
+{-# LANGUAGE UndecidableInstances #-}
+
+module Data.Pointed.Graph where
+
+import Control.Graphted.Class
+
+-- | Pointed functor.
+class GPointed (f :: p -> * -> *) where
+    type family Pure f :: p
+    type instance Pure f = Unit f
+
+    -- | Accessible only with type applications.
+    gpoint' :: forall t a. a -> f t a
+
+    gpoint :: forall a. a -> f (Pure f) a
+    gpoint = gpoint' @p @f @(Pure f)
+
+    {-# MINIMAL gpoint' #-}
diff --git a/src/Prelude/Graphted.hs b/src/Prelude/Graphted.hs
new file mode 100644
--- /dev/null
+++ b/src/Prelude/Graphted.hs
@@ -0,0 +1,170 @@
+{- |
+Module      :  Prelude.Graphted
+Description :  Prelude with operators overridden by graph-indexed implementations
+Copyright   :  (c) Aaron Friel
+License     :  BSD-3
+
+Maintainer  :  Aaron Friel <mayreply@aaronfriel.com>
+Stability   :  experimental
+Portability :  portable
+
+-}
+
+{-# LANGUAGE ApplicativeDo         #-}
+{-# LANGUAGE FlexibleContexts      #-}
+{-# LANGUAGE GADTs                 #-}
+{-# LANGUAGE NoImplicitPrelude     #-}
+{-# LANGUAGE PartialTypeSignatures #-}
+{-# LANGUAGE PolyKinds             #-}
+{-# LANGUAGE RebindableSyntax      #-}
+
+{-# OPTIONS_GHC -Wno-partial-type-signatures #-}
+
+module Prelude.Graphted (
+    -- Functor
+    fmap, (<$), (<$>),
+    -- Applicative
+    pure, (<*>), (*>), (<*),
+    -- Monad
+    return, (>>=), (=<<), (>>),
+    -- MonadFail
+    fail,
+    -- MonadPlus, MonadOr
+    zero, (<+>), (<|>),
+
+    -- Extra operators:
+    (<**>), liftA, liftA2, liftA3,
+    join, liftM, liftM2, liftM3, liftM4, liftM5, ap,
+
+    mapM_, sequence_,
+
+    module X
+    ) where
+
+
+import Prelude as X hiding (fail, fmap, mapM_, pure, return, sequence_, (*>),
+                     (<$), (<$>), (<*), (<*>), (=<<), (>>), (>>=))
+
+import Control.Graphted
+
+infixl 4 <$
+infixl 1 >>, >>=
+infixr 1 =<<
+infixl 4 <*>, <*, *>, <**>
+
+fmap :: GFunctor f => (a -> b) -> f i a -> f (Fmap f i) b
+fmap = gmap
+
+(<$) :: GFunctor f => b -> f i a -> f (Fconst f i) b
+(<$) = gconst
+
+(<$>) :: GFunctor f => (a -> b) -> f i a -> f (Fmap f i) b
+(<$>) = fmap
+
+pure :: GPointed f => a -> f (Pure f) a
+pure = gpoint
+
+(<*>) :: (GApplicative f, _) => f i (a -> b) -> f j a -> f (Apply f i j) b
+(<*>) = gap
+
+(*>) :: (GApplicative f, _) => f i a -> f j b -> f (Then f i j) b
+(*>)= gthen
+
+(<*) :: (GApplicative f, _) => f i a -> f j b -> f (But f i j) a
+(<*) = gbut
+
+return :: GPointed m => a -> m (Pure m) a
+return = gpoint
+
+(>>=) :: (GMonad m, Inv m i j) => m i a -> (a -> m j b) -> m (Bind m i j) b
+(>>=) = gbind
+
+(=<<) :: (GMonad m, Inv m i j) => (a -> m j b) -> m i a -> m (Bind m i j) b
+(=<<) = flip (>>=)
+
+zero :: GMonadZero m => m (Zero m) a
+zero = gzero
+
+fail :: GMonadFail m => String -> m (Fail m) a
+fail = gfail
+
+(<+>) :: (GMonadPlus f, _) => f i a -> f j a -> f (Plus f i j) a
+(<+>) = gplus
+
+(<|>) :: (GMonadOr f, _) => f i a -> f j a -> f (Or f i j) a
+(<|>) = gorelse
+
+-- Simplified binding, what GHC.Base would like to do but cannot for backwards compatbility.
+(>>) :: (GApplicative m, _) => m i a -> m j b -> m (Then m i j) b
+(>>) = gthen
+
+join :: (GMonad m, Inv m i j) => m i (m j b) -> m (Join m i j) b
+join = gjoin
+
+(<**>) :: (GApplicative f, _) => f i1 a -> f i2 (a -> b)
+       -> f (Apply f (Apply f (Pure f) i1) i2) b
+(<**>) = liftA2 (flip ($))
+
+liftA :: (GApplicative f, _) => (a -> b) -> f i1 a
+      -> f (Apply f (Pure f) i1) b
+liftA f a = pure f <*> a
+
+liftA2 :: (GApplicative f, _) => (a1 -> a2 -> b) -> f i1 a1 -> f i2 a2
+       -> f (Apply f (Apply f (Pure f) i1) i2) b
+liftA2 f a b = pure f <*> a <*> b
+
+liftA3 :: (GApplicative f, _) => (a1 -> a2 -> a3 -> b) -> f i1 a1 -> f i2 a2 -> f i3 a3
+       -> f (Apply f (Apply f (Apply f (Pure f) i1) i2) i3) b
+liftA3 f a b c = pure f <*> a <*> b <*> c
+
+liftM :: (GApplicative m, _) => (t -> b) -> m j t -> m (Fmap m j) b
+liftM f m1              = do { x1 <- m1; return (f x1) }
+
+liftM2 :: (GApplicative m, _)
+       => (t1 -> t -> b)
+       -> m i1 t1
+       -> m i t
+       -> m (Apply m (Fmap m i1) i) b
+liftM2 f m1 m2          = do { x1 <- m1; x2 <- m2; return (f x1 x2) }
+
+liftM3 :: (GApplicative m, _)
+       => (t2 -> t1 -> t -> b)
+       -> m i2 t2
+       -> m i1 t1
+       -> m i t
+       -> m (Apply m (Apply m (Fmap m i2) i1) i) b
+liftM3 f m1 m2 m3       = do { x1 <- m1; x2 <- m2; x3 <- m3; return (f x1 x2 x3) }
+
+liftM4 :: (GApplicative m, _)
+       => (t3 -> t2 -> t1 -> t -> b)
+       -> m i3 t3
+       -> m i2 t2
+       -> m i1 t1
+       -> m i t
+       -> m (Apply m (Apply m (Apply m (Fmap m i3) i2) i1) i) b
+liftM4 f m1 m2 m3 m4    = do { x1 <- m1; x2 <- m2; x3 <- m3; x4 <- m4; return (f x1 x2 x3 x4) }
+
+liftM5 :: (GApplicative m, _)
+       => (t4 -> t3 -> t2 -> t1 -> t -> b)
+       -> m i4 t4
+       -> m i3 t3
+       -> m i2 t2
+       -> m i1 t1
+       -> m i t
+       -> m (Apply m (Apply m (Apply m (Apply m (Fmap m i4) i3) i2) i1) i) b
+liftM5 f m1 m2 m3 m4 m5 = do { x1 <- m1; x2 <- m2; x3 <- m3; x4 <- m4; x5 <- m5; return (f x1 x2 x3 x4 x5) }
+
+ap :: (GApplicative m, Inv m (Fmap m i) j) => m i (t -> b) -> m j t -> m (Apply m (Fmap m i) j) b
+ap m1 m2 = do { x1 <- m1; x2 <- m2; return (x1 x2) }
+
+-- Recursive bindings may be impossible. This type is inferred, but not always satisfiable.
+-- We will need to implement our own folds and control flow.
+mapM_ :: (GApplicative m, Foldable t, Apply m (Fmap m i) (Pure m) ~ Pure m, _)
+      => (a1 -> m i a) -> t a1 -> m (Pure m) ()
+mapM_ f = foldr ((>>) . f) (return ())
+
+-- As above.
+sequence_ :: (GApplicative m, Foldable t, Apply m (Fmap m i) (Pure m) ~ Pure m, _)
+          => t (m i a) -> m (Pure m) ()
+sequence_ = foldr (>>) (return ())
+
