diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
--- a/.travis.yml
+++ /dev/null
@@ -1,85 +0,0 @@
-# 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/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,7 +1,7 @@
-0.1.5
+0.2
 ----
-* Changed the representation of `Zombie` too
-* Added `deboneBy`
+
+* Removed `unbone`
 
 0.1.4
 ----
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -4,7 +4,7 @@
 [![Build Status](https://travis-ci.org/fumieval/monad-skeleton.svg?branch=master)](https://travis-ci.org/fumieval/monad-skeleton)
 [![Hackage](https://img.shields.io/hackage/v/monad-skeleton.svg)](https://hackage.haskell.org/package/monad-skeleton)
 
-This package provides `Skeleton`, an operational monad. The internal encoding
+This package provides `Skeleton`, an operational monad (i.e. free monad that does not require the Functor implementation). The internal encoding
 gives O(1) bind and monadic reflection.
 
 `Skeleton` promotes unit instructions to a monad. It is isomorphic to
diff --git a/monad-skeleton.cabal b/monad-skeleton.cabal
--- a/monad-skeleton.cabal
+++ b/monad-skeleton.cabal
@@ -1,23 +1,23 @@
+cabal-version:       2.4
 name:                monad-skeleton
-version:             0.1.5
+version:             0.2
 synopsis:            Monads of program skeleta
 description:         Fast operational monad library
 homepage:            https://github.com/fumieval/monad-skeleton
 bug-reports:         http://github.com/fumieval/monad-skeleton/issues
-license:             BSD3
+license:             BSD-3-Clause
 license-file:        LICENSE
 author:              Fumiaki Kinoshita
 maintainer:          Fumiaki Kinoshita <fumiexcel@gmail.com>
-copyright:           Copyright (c) 2017 Fumiaki Kinoshita
+copyright:           Copyright (c) 2021 Fumiaki Kinoshita
 category:            Control, Monads
 build-type:          Simple
-cabal-version:       >=1.10
+
 extra-source-files:
-  .travis.yml
   .gitignore
   README.md
   CHANGELOG.md
-tested-with: GHC == 7.8.4, GHC == 7.10.3, GHC == 8.0.2
+tested-with: GHC == 8.10.7, GHC == 9.2.1
 
 source-repository head
   type: git
@@ -27,7 +27,7 @@
   exposed-modules:     Control.Monad.Skeleton
     , Control.Monad.Skeleton.Internal
     , Control.Monad.Zombie
-  build-depends:       base == 4.*
+  build-depends:       base >= 4.9 && <4.17
   hs-source-dirs: src
-  ghc-options: -Wall
+  ghc-options: -Wall -Wcompat
   default-language:    Haskell2010
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,6 @@
-{-# LANGUAGE BangPatterns, RankNTypes, GADTs, ScopedTypeVariables #-}
+{-# LANGUAGE RankNTypes #-}
+{-# LANGUAGE GADTs #-}
+{-# LANGUAGE ScopedTypeVariables #-}
 module Control.Monad.Skeleton (MonadView(..)
   , hoistMV
   , iterMV
@@ -6,7 +8,6 @@
   , bone
   , debone
   , deboneBy
-  , unbone
   , boned
   , hoistSkeleton
   ) where
@@ -17,13 +18,13 @@
 import Control.Monad.Skeleton.Internal
 import Prelude hiding (id, (.))
 
--- | Re-add a bone.
+-- | Re-add a bone. Inverse of 'debone'
 boned :: MonadView t (Skeleton t) a -> Skeleton t a
 boned (Return a) = ReturnS a
 boned (t :>>= k) = BindS t $ Leaf $ Kleisli k
 {-# INLINE boned #-}
 
--- | Pick a bone from a 'Skeleton'.
+-- | Extract the first instruction in 'Skeleton'.
 debone :: Skeleton t a -> MonadView t (Skeleton t) a
 debone (ReturnS a) = Return a
 debone (BindS t c0) = t :>>= go c0 where
@@ -32,8 +33,8 @@
     ReturnS b -> go c' b
     BindS t' c'' -> BindS t' (Tree c'' c')
 
--- | Pick a bone from a 'Skeleton' by a function.
--- It's useful when used with @LambdaCase@.
+-- | Continuation-passing variant of 'debone'
+-- which allows nicer expression using @LambdaCase@.
 --
 -- Usecase:
 --
@@ -45,12 +46,6 @@
 deboneBy f s = f (debone s)
 {-# INLINE deboneBy #-}
 
--- | Uncommon synonym for 'debone'.
-unbone :: Skeleton t a -> MonadView t (Skeleton t) a
-unbone = debone
-{-# INLINE unbone #-}
-{-# DEPRECATED unbone "Use debone instead" #-}
-
 -- | A skeleton that has only one bone.
 bone :: t a -> Skeleton t a
 bone t = BindS t $ Leaf $ Kleisli ReturnS
@@ -75,7 +70,7 @@
   fmap f (t :>>= k) = t :>>= fmap f . k
   {-# INLINE fmap #-}
 
--- | Transform the action and the continuation.
+-- | Transform the instruction as well as the continuation.
 hoistMV :: (forall x. s x -> t x) -> (m a -> n a) -> MonadView s m a -> MonadView t n a
 hoistMV _ _ (Return a) = Return a
 hoistMV f g (t :>>= k) = f t :>>= g . k
@@ -90,8 +85,8 @@
 {-# INLINE iterMV #-}
 
 -- | @'Skeleton' t@ is a monadic skeleton (operational monad) made out of 't'.
--- Skeletons can be fleshed out by getting transformed to other monads.
--- It provides O(1) ('>>=') and 'debone', the monadic reflection.
+-- Skeletons can be fleshed out by interpreting the instructions.
+-- It provides O(1) ('>>=') and 'debone'.
 data Skeleton t a where
   ReturnS :: a -> Skeleton t a
   BindS :: t a -> Cat (Kleisli (Skeleton t)) a b -> Skeleton t b
@@ -101,15 +96,14 @@
   {-# INLINE fmap #-}
 
 instance Applicative (Skeleton t) where
-  pure = return
+  pure = ReturnS
   {-# INLINE pure #-}
   (<*>) = ap
   {-# INLINE (<*>) #-}
-  (*>) = (>>)
-  {-# INLINE (*>) #-}
+  ReturnS _ *> k = k
+  BindS t c *> k = BindS t (c |> Kleisli (const k))
   a <* b = a >>= \x -> b >> return x
 
 instance Monad (Skeleton t) where
-  return = ReturnS
   ReturnS a >>= k = k a
   BindS t c >>= k = BindS t (c |> Kleisli k)
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,9 +1,14 @@
-{-# LANGUAGE PolyKinds, GADTs, Rank2Types, ScopedTypeVariables, Trustworthy #-}
+{-# LANGUAGE PolyKinds #-}
+{-# LANGUAGE GADTs #-}
+{-# LANGUAGE RankNTypes #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE Trustworthy #-}
 module Control.Monad.Skeleton.Internal (Cat(..), transCat, (|>), viewL, transKleisli) where
 
 import Control.Arrow
 import Unsafe.Coerce
 
+-- | Type-aligned catenable queue
 data Cat k a b where
   Leaf :: k a b -> Cat k a b
   Tree :: Cat k a b -> Cat k b c -> Cat k a c
@@ -17,6 +22,7 @@
 s |> k = Tree s (Leaf k)
 {-# INLINE (|>) #-}
 
+-- | Match on the leftmost element. It gradually rotates the nodes so that following calls to 'viewL' is faster.
 viewL :: forall k a b r. Cat k a b
   -> (k a b -> r)
   -> (forall x. k a x -> Cat k x b -> r)
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,8 +1,11 @@
-{-# LANGUAGE Rank2Types, ScopedTypeVariables, GADTs #-}
+{-# LANGUAGE RankNTypes #-}
+{-# LANGUAGE GADTs #-}
+{-# LANGUAGE ScopedTypeVariables #-}
 module Control.Monad.Zombie (Zombie(..)
   , liftZ
   , embalm
   , disembalm
+  , disembalmBy
   , hoistZombie
   ) where
 import Control.Applicative
@@ -22,9 +25,11 @@
   fmap = liftM
 
 instance Applicative (Zombie t) where
-  pure = return
+  pure a = ReturnZ a Sunlight
   (<*>) = ap
-  (*>) = (>>)
+  Sunlight *> _ = Sunlight
+  ReturnZ _ xs *> k = k <|> (xs *> k)
+  BindZ x c xs *> k = BindZ x (c |> Kleisli (const k)) (xs *> k)
 
 instance Alternative (Zombie t) where
   empty = Sunlight
@@ -33,7 +38,6 @@
   BindZ x c xs <|> ys = BindZ x c (xs <|> ys)
 
 instance Monad (Zombie t) where
-  return a = ReturnZ a Sunlight
   Sunlight >>= _ = Sunlight
   ReturnZ a xs >>= k = k a <|> (xs >>= k)
   BindZ x c xs >>= k = BindZ x (c |> Kleisli k) (xs >>= k)
@@ -55,18 +59,26 @@
 
 -- | Decompose a zombie as a list of possibilities.
 disembalm :: Zombie t a -> [MonadView t (Zombie t) a]
-disembalm Sunlight = []
-disembalm (ReturnZ x xs) = Return x : disembalm xs
-disembalm (BindZ x d xs) = (x :>>= disembalm_go d) : disembalm xs
+disembalm = disembalmBy [] (:)
+{-# INLINE disembalm #-}
 
+-- | Decompose a zombie as a list of possibilitie and fold the list.
+disembalmBy :: r -> (MonadView t (Zombie t) a -> r -> r) -> Zombie t a -> r
+disembalmBy e r = go where
+  go Sunlight = e
+  go (ReturnZ x xs) = Return x `r` go xs
+  go (BindZ x c xs) = (x :>>= disembalm_go c) `r` go xs
+{-# INLINE disembalmBy #-}
+
 disembalm_go :: Cat (Kleisli (Zombie t)) a b -> a -> Zombie t b
-disembalm_go c a = viewL c (\(Kleisli k) -> k a) $ \(Kleisli k) c' -> disembalm_go2 (k a) c'
+disembalm_go c a = viewL c (\k -> runKleisli k a) $
+  \k d -> disembalm_go2 d $ runKleisli k a
 
-disembalm_go2 :: Zombie t a -> Cat (Kleisli (Zombie t)) a b -> Zombie t b
-disembalm_go2 x c = case x of
-  Sunlight -> Sunlight
-  ReturnZ a xs -> disembalm_go c a <|> disembalm_go2 xs c
-  BindZ t c' xs -> BindZ t (Tree c' c) $ disembalm_go2 xs c
+disembalm_go2 :: Cat (Kleisli (Zombie t)) a b -> Zombie t a -> Zombie t b
+disembalm_go2 c = go where
+  go Sunlight = Sunlight
+  go (ReturnZ a xs) = disembalm_go c a <|> go xs
+  go (BindZ t d xs) = BindZ t (Tree d c) $ go xs
 
 -- | Like 'hoistSkeleton'
 hoistZombie :: forall s t a. (forall x. s x -> t x) -> Zombie s a -> Zombie t a
