diff --git a/.gitignore b/.gitignore
new file mode 100644
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,59 @@
+dist
+cabal-dev
+*.o
+*.hi
+*.chi
+*.chs.h
+.virtualenv
+.hsenv
+.cabal-sandbox/
+cabal.sandbox.config
+cabal.config
+.stack-work
+
+# =========================
+# Operating System Files
+# =========================
+
+# OSX
+# =========================
+
+.DS_Store
+.AppleDouble
+.LSOverride
+
+# Thumbnails
+._*
+
+# Files that might appear on external disk
+.Spotlight-V100
+.Trashes
+
+# Directories potentially created on remote AFP share
+.AppleDB
+.AppleDesktop
+Network Trash Folder
+Temporary Items
+.apdisk
+
+# Windows
+# =========================
+
+# Windows image file caches
+Thumbs.db
+ehthumbs.db
+
+# Folder config file
+Desktop.ini
+
+# Recycle Bin used on file shares
+$RECYCLE.BIN/
+
+# Windows Installer files
+*.cab
+*.msi
+*.msm
+*.msp
+
+# Windows shortcuts
+*.lnk
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,85 @@
+# This file has been generated -- see https://github.com/hvr/multi-ghc-travis
+language: c
+sudo: false
+
+cache:
+  directories:
+    - $HOME/.cabsnap
+    - $HOME/.cabal/packages
+
+before_cache:
+  - rm -fv $HOME/.cabal/packages/hackage.haskell.org/build-reports.log
+  - rm -fv $HOME/.cabal/packages/hackage.haskell.org/00-index.tar
+
+matrix:
+  include:
+    - env: CABALVER=1.18 GHCVER=7.8.4
+      compiler: ": #GHC 7.8.4"
+      addons: {apt: {packages: [cabal-install-1.18,ghc-7.8.4], sources: [hvr-ghc]}}
+    - env: CABALVER=1.22 GHCVER=7.10.3
+      compiler: ": #GHC 7.10.3"
+      addons: {apt: {packages: [cabal-install-1.22,ghc-7.10.3], sources: [hvr-ghc]}}
+    - env: CABALVER=1.24 GHCVER=8.0.2
+      compiler: ": #GHC 8.0.2"
+      addons: {apt: {packages: [cabal-install-1.24,ghc-8.0.2], sources: [hvr-ghc]}}
+    - env: CABALVER=head GHCVER=head
+      addons: {apt: {packages: [cabal-install-head,ghc-head],  sources: [hvr-ghc]}}
+  allow_failures:
+    - env: CABALVER=head GHCVER=head
+before_install:
+ - unset CC
+ - export PATH=/opt/ghc/$GHCVER/bin:/opt/cabal/$CABALVER/bin:$PATH
+
+install:
+ - cabal --version
+ - echo "$(ghc --version) [$(ghc --print-project-git-commit-id 2> /dev/null || echo '?')]"
+ - if [ -f $HOME/.cabal/packages/hackage.haskell.org/00-index.tar.gz ];
+   then
+     zcat $HOME/.cabal/packages/hackage.haskell.org/00-index.tar.gz >
+          $HOME/.cabal/packages/hackage.haskell.org/00-index.tar;
+   fi
+ - travis_retry cabal update -v
+ - sed -i 's/^jobs:/-- jobs:/' ${HOME}/.cabal/config
+ - cabal install --only-dependencies --enable-tests --enable-benchmarks --dry -v > installplan.txt
+ - sed -i -e '1,/^Resolving /d' installplan.txt; cat installplan.txt
+
+# check whether current requested install-plan matches cached package-db snapshot
+ - if diff -u $HOME/.cabsnap/installplan.txt installplan.txt;
+   then
+     echo "cabal build-cache HIT";
+     rm -rfv .ghc;
+     cp -a $HOME/.cabsnap/ghc $HOME/.ghc;
+     cp -a $HOME/.cabsnap/lib $HOME/.cabsnap/share $HOME/.cabsnap/bin $HOME/.cabal/;
+   else
+     echo "cabal build-cache MISS";
+     rm -rf $HOME/.cabsnap;
+     mkdir -p $HOME/.ghc $HOME/.cabal/lib $HOME/.cabal/share $HOME/.cabal/bin;
+     cabal install --only-dependencies --enable-tests --enable-benchmarks;
+   fi
+
+# snapshot package-db on cache miss
+ - if [ ! -d $HOME/.cabsnap ];
+   then
+      echo "snapshotting package-db to build-cache";
+      mkdir $HOME/.cabsnap;
+      cp -a $HOME/.ghc $HOME/.cabsnap/ghc;
+      cp -a $HOME/.cabal/lib $HOME/.cabal/share $HOME/.cabal/bin installplan.txt $HOME/.cabsnap/;
+   fi
+
+# Here starts the actual work to be performed for the package under test;
+# any command which exits with a non-zero exit code causes the build to fail.
+script:
+ - if [ -f configure.ac ]; then autoreconf -i; fi
+ - cabal configure --enable-tests --enable-benchmarks -v2  # -v2 provides useful information for debugging
+ - cabal build   # this builds all libraries and executables (including tests/benchmarks)
+ - cabal test
+ - cabal check
+ - cabal sdist   # tests that a source-distribution can be generated
+
+# Check that the resulting source distribution can be built & installed.
+# If there are no other `.tar.gz` files in `dist`, this can be even simpler:
+# `cabal install --force-reinstalls dist/*-*.tar.gz`
+ - SRC_TGZ=$(cabal info . | awk '{print $2;exit}').tar.gz &&
+   (cd dist && cabal install --force-reinstalls "$SRC_TGZ")
+
+# EOF
diff --git a/README.md b/README.md
new file mode 100644
--- /dev/null
+++ b/README.md
@@ -0,0 +1,41 @@
+monad-skeleton
+======================
+
+[![Build Status](https://travis-ci.org/fumieval/monad-skeleton.svg?branch=master)](https://travis-ci.org/fumieval/monad-skeleton)
+[![Hackage](https://budueba.com/hackage/monad-skeleton)](https://hackage.haskell.org/package/monad-skeleton)
+
+This package provides `Skeleton`, an operational monad. The internal encoding
+gives O(1) bind and monadic reflection.
+
+`Skeleton` promotes unit instructions to a monad. It is isomorphic to
+`MonadView (Skeleton t)`:
+
+```haskell
+data MonadView t m x where
+  Return :: a -> MonadView t m a
+  (:>>=) :: !(t a) -> (a -> m b) -> MonadView t m b
+
+boned :: MonadView t (Skeleton t) a -> Skeleton t a
+debone :: Skeleton t a -> MonadView t (Skeleton t) a
+```
+
+GADTs are handy to define instructions:
+
+```haskell
+data Interaction x where
+  Get :: Interacton String
+  Put :: String -> Interaction ()
+
+echo :: Skeleton Interaction ()
+echo = bone Get >>= bone . Put
+```
+
+Use `debone` to interpret a computation.
+
+```haskell
+interpret :: Skeleton Interaction a -> IO a
+interpret m = case debone m of
+  Return a -> return a
+  Get :>>= k -> getLine >>= interpret . k
+  Put s :>>= k -> putStrLn s >>= interpret . k
+```
diff --git a/monad-skeleton.cabal b/monad-skeleton.cabal
--- a/monad-skeleton.cabal
+++ b/monad-skeleton.cabal
@@ -1,5 +1,5 @@
 name:                monad-skeleton
-version:             0.1.3.1
+version:             0.1.3.2
 synopsis:            Monads of program skeleta
 description:         Fast operational monad library
 homepage:            https://github.com/fumieval/monad-skeleton
@@ -12,6 +12,11 @@
 category:            Control, Monads
 build-type:          Simple
 cabal-version:       >=1.10
+extra-source-files:
+  .travis.yml
+  .gitignore
+  README.md
+tested-with: GHC == 7.8.4, GHC == 7.10.3, GHC == 8.0.2
 
 source-repository head
   type: git
diff --git a/src/Control/Monad/Skeleton.hs b/src/Control/Monad/Skeleton.hs
--- a/src/Control/Monad/Skeleton.hs
+++ b/src/Control/Monad/Skeleton.hs
@@ -1,4 +1,4 @@
-{-# LANGUAGE BangPatterns, Trustworthy, RankNTypes, GADTs, ScopedTypeVariables #-}
+{-# LANGUAGE BangPatterns, RankNTypes, GADTs, ScopedTypeVariables #-}
 module Control.Monad.Skeleton (MonadView(..)
   , hoistMV
   , iterMV
@@ -16,7 +16,6 @@
 import Control.Applicative
 import Control.Monad
 import Control.Category
-import Unsafe.Coerce
 import Control.Monad.Skeleton.Internal
 import Prelude hiding (id, (.))
 
@@ -107,7 +106,3 @@
 instance Monad (Skeleton t) where
   return a = Skeleton $ Spine (Return a) id
   Skeleton (Spine t c) >>= k = Skeleton $ Spine t (c |> Kleisli k)
-
-transKleisli :: (m b -> n b) -> Kleisli m a b -> Kleisli n a b
-transKleisli f = unsafeCoerce (f.)
-{-# INLINE transKleisli #-}
diff --git a/src/Control/Monad/Skeleton/Internal.hs b/src/Control/Monad/Skeleton/Internal.hs
--- a/src/Control/Monad/Skeleton/Internal.hs
+++ b/src/Control/Monad/Skeleton/Internal.hs
@@ -1,7 +1,9 @@
-{-# LANGUAGE PolyKinds, GADTs, Rank2Types, ScopedTypeVariables #-}
-module Control.Monad.Skeleton.Internal (Cat(..), transCat, (|>), viewL) where
+{-# LANGUAGE PolyKinds, GADTs, Rank2Types, ScopedTypeVariables, Trustworthy #-}
+module Control.Monad.Skeleton.Internal (Cat(..), transCat, (|>), viewL, transKleisli) where
 
+import Control.Arrow
 import Control.Category
+import Unsafe.Coerce
 
 data Cat k a b where
   Empty :: Cat k a a
@@ -35,3 +37,7 @@
   {-# INLINE id #-}
   (.) = flip Tree
   {-# INLINE (.) #-}
+
+transKleisli :: (m b -> n b) -> Kleisli m a b -> Kleisli n a b
+transKleisli f = unsafeCoerce (f Prelude..)
+{-# INLINE transKleisli #-}
diff --git a/src/Control/Monad/Zombie.hs b/src/Control/Monad/Zombie.hs
--- a/src/Control/Monad/Zombie.hs
+++ b/src/Control/Monad/Zombie.hs
@@ -1,3 +1,4 @@
+{-# LANGUAGE Rank2Types, ScopedTypeVariables #-}
 module Control.Monad.Zombie where
 import Control.Applicative
 import Control.Arrow
@@ -30,9 +31,15 @@
   mzero = empty
   mplus = (<|>)
 
+-- | Lift a unit action
+liftZ :: t a -> Zombie t a
+liftZ t = embalm (t :>>= return)
+{-# INLINE liftZ #-}
+
 -- | Turn a decomposed form into a composed form.
 embalm :: MonadView t (Zombie t) a -> Zombie t a
 embalm t = Zombie [Spine t id]
+{-# INLINE embalm #-}
 
 -- | Decompose a zombie as a list of possibilities.
 disembalm :: Zombie t a -> [MonadView t (Zombie t) a]
@@ -43,3 +50,11 @@
       Zombie ss' -> disembalm $ Zombie $ map (graftSpine c') ss'
     t :>>= k -> return $ t :>>= \a -> case k a of
       Zombie ss' -> Zombie $ map (graftSpine c) ss'
+
+-- | Like 'hoistSkeleton'
+hoistZombie :: forall s t a. (forall x. s x -> t x) -> Zombie s a -> Zombie t a
+hoistZombie f = go where
+  go :: forall x. Zombie s x -> Zombie t x
+  go (Zombie ss) = Zombie [Spine (hoistMV f go v) (transCat (transKleisli go) c)
+    | Spine v c <- ss]
+{-# INLINE hoistZombie #-}
