diff --git a/Data/Has.hs b/Data/Has.hs
new file mode 100644
--- /dev/null
+++ b/Data/Has.hs
@@ -0,0 +1,276 @@
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE FlexibleInstances #-}
+
+{-|
+Module      : Data.Has
+Description : Simple extensible product
+Copyright   : (c) Winterland, 2016
+License     : BSD
+Maintainer  : drkoster@qq.com
+Stability   : experimental
+Portability : PORTABLE
+
+This module provide 'Has' class which provide simple extensible product.
+The use case for this class is illustrated as following:
+
+@
+ \{\-\# LANGUAGE FlexibleContexts \#\-\}
+
+ -- in some library code
+ ...
+ logInAnyReaderHasLogger :: (Has Logger r, MonadReader r m) => LogString -> m ()
+ logInAnyReaderHasLogger s = asks get >>= logWithLogger s
+
+ queryInAnyReaderHasSQL :: (Has SqlBackEnd r, MonadReader r m) => Query -> m a
+ queryInAnyReaderHasSQL q = asks get >>= queryWithSQL q
+ ...
+
+ -- now you want to use these effects together
+ ...
+ logger <- initLogger  ...
+ sql <- initSqlBackEnd ...
+
+ (`runReader` (logger, sql)) $ do
+       ...
+       logInAnyReaderHasLogger ...
+       ...
+       x <- queryInAnyReaderHasSQL ...
+       ...
+@
+
+If you need multiple elements with same type, you can use <http://hackage.haskell.org/package/tagged tagged>
+like:
+
+@
+(Has (Tagged \"StdLogger\" Logger) r, Has (Tagged \"FileLogger\" Logger) r, ...) => ...
+
+runYourMonad ... ( stdLogger :: Tagged \"StdLogger\" Logger
+                 , fileLogger :: Tagged \"FileLogger\" Logger, ...)
+@
+
+Or you can define newtypes(which is less verbose and require no dependency):
+
+@
+newtype StdLogger = StdLogger Logger
+newtype FileLogger = FileLogger Logger
+
+runYourMonad ... (StdLogger stdLogger, FileLogger fileLogger)
+@
+
+Polymorphic values, such as numeric and string literals(with OverloadedString Enabled)
+may lead to type inference failure, you simply need type annotations in these cases:
+
+@ ... (3 :: Int, "hello" :: String, ...) @
+
+-}
+
+module Data.Has where
+
+-- | A type class for extensible product.
+--
+-- We provide instances for tuples up to 8 elements by default.
+-- You can define your own instance of 'Has', but most of the time tuples will do fine.
+--
+class Has a t where
+    get :: t -> a
+    modify :: (a -> a) -> t -> t
+
+instance Has a a where
+    get = id
+    {-# INLINABLE get #-}
+    modify = id
+    {-# INLINABLE modify #-}
+
+instance Has a (a, b) where
+    get (a, _) = a
+    {-# INLINABLE get #-}
+    modify f (a, b) = (f a, b)
+    {-# INLINABLE modify #-}
+instance Has b (a, b) where
+    get (_, b) = b
+    {-# INLINABLE get #-}
+    modify f (a, b) = (a, f b)
+    {-# INLINABLE modify #-}
+
+--------------------------------------------------------------------------------
+
+instance Has a (a, b, c) where
+    get (a, _, _) = a
+    {-# INLINABLE get #-}
+    modify f (a, b, c) = (f a, b, c)
+    {-# INLINABLE modify #-}
+instance Has b (a, b, c) where
+    get (_, b, _) = b
+    {-# INLINABLE get #-}
+    modify f (a, b, c) = (a, f b, c)
+    {-# INLINABLE modify #-}
+instance Has c (a, b, c) where
+    get (_, _, c) = c
+    {-# INLINABLE get #-}
+    modify f (a, b, c) = (a, b, f c)
+    {-# INLINABLE modify #-}
+
+--------------------------------------------------------------------------------
+
+instance Has a (a, b, c, d) where
+    get (a, _, _, _) = a
+    {-# INLINABLE get #-}
+    modify f (a, b, c, d) = (f a, b, c, d)
+    {-# INLINABLE modify #-}
+instance Has b (a, b, c, d) where
+    get (_, b, _, _) = b
+    {-# INLINABLE get #-}
+    modify f (a, b, c, d) = (a, f b, c, d)
+    {-# INLINABLE modify #-}
+instance Has c (a, b, c, d) where
+    get (_, _, c, _) = c
+    {-# INLINABLE get #-}
+    modify f (a, b, c, d) = (a, b, f c, d)
+    {-# INLINABLE modify #-}
+instance Has d (a, b, c, d) where
+    get (_, _, _, d) = d
+    {-# INLINABLE get #-}
+    modify f (a, b, c, d) = (a, b, c, f d)
+    {-# INLINABLE modify #-}
+
+--------------------------------------------------------------------------------
+
+instance Has a (a, b, c, d, e) where
+    get (a, _, _, _, _) = a
+    {-# INLINABLE get #-}
+    modify f (a, b, c, d, e) = (f a, b, c, d, e)
+    {-# INLINABLE modify #-}
+instance Has b (a, b, c, d, e) where
+    get (_, b, _, _, _) = b
+    {-# INLINABLE get #-}
+    modify f (a, b, c, d, e) = (a, f b, c, d, e)
+    {-# INLINABLE modify #-}
+instance Has c (a, b, c, d, e) where
+    get (_, _, c, _, _) = c
+    {-# INLINABLE get #-}
+    modify f (a, b, c, d, e) = (a, b, f c, d, e)
+    {-# INLINABLE modify #-}
+instance Has d (a, b, c, d, e) where
+    get (_, _, _, d, _) = d
+    {-# INLINABLE get #-}
+    modify f (a, b, c, d, e) = (a, b, c, f d, e)
+    {-# INLINABLE modify #-}
+instance Has e (a, b, c, d, e) where
+    get (_, _, _, _, e) = e
+    {-# INLINABLE get #-}
+    modify f (a, b, c, d, e) = (a, b, c, d, f e)
+    {-# INLINABLE modify #-}
+
+--------------------------------------------------------------------------------
+
+instance Has a (a, b, c, d, e, f) where
+    get (a, _, _, _, _, _) = a
+    {-# INLINABLE get #-}
+    modify ff (a, b, c, d, e, f) = (ff a, b, c, d, e, f)
+    {-# INLINABLE modify #-}
+instance Has b (a, b, c, d, e, f) where
+    get (_, b, _, _, _, _) = b
+    {-# INLINABLE get #-}
+    modify ff (a, b, c, d, e, f) = (a, ff b, c, d, e, f)
+    {-# INLINABLE modify #-}
+instance Has c (a, b, c, d, e, f) where
+    get (_, _, c, _, _, _) = c
+    {-# INLINABLE get #-}
+    modify ff (a, b, c, d, e, f) = (a, b, ff c, d, e, f)
+    {-# INLINABLE modify #-}
+instance Has d (a, b, c, d, e, f) where
+    get (_, _, _, d, _, _) = d
+    {-# INLINABLE get #-}
+    modify ff (a, b, c, d, e, f) = (a, b, c, ff d, e, f)
+    {-# INLINABLE modify #-}
+instance Has e (a, b, c, d, e, f) where
+    get (_, _, _, _, e, _) = e
+    {-# INLINABLE get #-}
+    modify ff (a, b, c, d, e, f) = (a, b, c, d, ff e, f)
+    {-# INLINABLE modify #-}
+instance Has f (a, b, c, d, e, f) where
+    get (_, _, _, _, _, f) = f
+    {-# INLINABLE get #-}
+    modify ff (a, b, c, d, e, f) = (a, b, c, d, e, ff f)
+    {-# INLINABLE modify #-}
+
+--------------------------------------------------------------------------------
+
+instance Has a (a, b, c, d, e, f, g) where
+    get (a, _, _, _, _, _, _) = a
+    {-# INLINABLE get #-}
+    modify ff (a, b, c, d, e, f, g) = (ff a, b, c, d, e, f, g)
+    {-# INLINABLE modify #-}
+instance Has b (a, b, c, d, e, f, g) where
+    get (_, b, _, _, _, _, _) = b
+    {-# INLINABLE get #-}
+    modify ff (a, b, c, d, e, f, g) = (a, ff b, c, d, e, f, g)
+    {-# INLINABLE modify #-}
+instance Has c (a, b, c, d, e, f, g) where
+    get (_, _, c, _, _, _, _) = c
+    {-# INLINABLE get #-}
+    modify ff (a, b, c, d, e, f, g) = (a, b, ff c, d, e, f, g)
+    {-# INLINABLE modify #-}
+instance Has d (a, b, c, d, e, f, g) where
+    get (_, _, _, d, _, _, _) = d
+    {-# INLINABLE get #-}
+    modify ff (a, b, c, d, e, f, g) = (a, b, c, ff d, e, f, g)
+    {-# INLINABLE modify #-}
+instance Has e (a, b, c, d, e, f, g) where
+    get (_, _, _, _, e, _, _) = e
+    {-# INLINABLE get #-}
+    modify ff (a, b, c, d, e, f, g) = (a, b, c, d, ff e, f, g)
+    {-# INLINABLE modify #-}
+instance Has f (a, b, c, d, e, f, g) where
+    get (_, _, _, _, _, f, _) = f
+    {-# INLINABLE get #-}
+    modify ff (a, b, c, d, e, f, g) = (a, b, c, d, e, ff f, g)
+    {-# INLINABLE modify #-}
+instance Has g (a, b, c, d, e, f, g) where
+    get (_, _, _, _, _, _, g) = g
+    {-# INLINABLE get #-}
+    modify ff (a, b, c, d, e, f, g) = (a, b, c, d, e, f, ff g)
+    {-# INLINABLE modify #-}
+
+--------------------------------------------------------------------------------
+
+instance Has a (a, b, c, d, e, f, g, h) where
+    get (a, _, _, _, _, _, _, _) = a
+    {-# INLINABLE get #-}
+    modify ff (a, b, c, d, e, f, g, h) = (ff a, b, c, d, e, f, g, h)
+    {-# INLINABLE modify #-}
+instance Has b (a, b, c, d, e, f, g, h) where
+    get (_, b, _, _, _, _, _, _) = b
+    {-# INLINABLE get #-}
+    modify ff (a, b, c, d, e, f, g, h) = (a, ff b, c, d, e, f, g, h)
+    {-# INLINABLE modify #-}
+instance Has c (a, b, c, d, e, f, g, h) where
+    get (_, _, c, _, _, _, _, _) = c
+    {-# INLINABLE get #-}
+    modify ff (a, b, c, d, e, f, g, h) = (a, b, ff c, d, e, f, g, h)
+    {-# INLINABLE modify #-}
+instance Has d (a, b, c, d, e, f, g, h) where
+    get (_, _, _, d, _, _, _, _) = d
+    {-# INLINABLE get #-}
+    modify ff (a, b, c, d, e, f, g, h) = (a, b, c, ff d, e, f, g, h)
+    {-# INLINABLE modify #-}
+instance Has e (a, b, c, d, e, f, g, h) where
+    get (_, _, _, _, e, _, _, _) = e
+    {-# INLINABLE get #-}
+    modify ff (a, b, c, d, e, f, g, h) = (a, b, c, d, ff e, f, g, h)
+    {-# INLINABLE modify #-}
+instance Has f (a, b, c, d, e, f, g, h) where
+    get (_, _, _, _, _, f, _, _) = f
+    {-# INLINABLE get #-}
+    modify ff (a, b, c, d, e, f, g, h) = (a, b, c, d, e, ff f, g, h)
+    {-# INLINABLE modify #-}
+instance Has g (a, b, c, d, e, f, g, h) where
+    get (_, _, _, _, _, _, g, _) = g
+    {-# INLINABLE get #-}
+    modify ff (a, b, c, d, e, f, g, h) = (a, b, c, d, e, f, ff g, h)
+    {-# INLINABLE modify #-}
+instance Has h (a, b, c, d, e, f, g, h) where
+    get (_, _, _, _, _, _, _, h) = h
+    {-# INLINABLE get #-}
+    modify ff (a, b, c, d, e, f, g, h) = (a, b, c, d, e, f, g, ff h)
+    {-# INLINABLE modify #-}
diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,30 @@
+Copyright (c) 2016, winterland1989
+
+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 winterland1989 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 @@
+data-has
+========
+
+[![Hackage](https://img.shields.io/hackage/v/data-has.svg?style=flat)](http://hackage.haskell.org/package/data-has)
+[![Build Status](https://travis-ci.org/winterland1989/data-has.svg)](https://travis-ci.org/winterland1989/data-has)
+
+A simple extensible product system, a typical usage is to free you from considering how to layer your monad stack, because your can now extend your monad in one layer:
+
+```haskell
+ {-# LANGUAGE FlexibleContexts #-}
+
+ -- in some library code
+ ...
+ logInAnyReaderHasLogger :: (Has Logger r, MonadReader r m) => LogString -> m ()
+ logInAnyReaderHasLogger s = asks get >>= logWithLogger s
+
+ queryInAnyReaderHasSQL :: (Has SqlBackEnd r, MonadReader r m) => Query -> m a
+ queryInAnyReaderHasSQL q = asks get >>= queryWithSQL q
+ ...
+
+ -- now you want to use these effects together
+ ...
+ logger <- initLogger  ...
+ sql <- initSqlBackEnd ...
+
+ (`runReader` (logger, sql)) $ do
+       ...
+       logInAnyReaderHasLogger ...
+       ...
+       x <- queryInAnyReaderHasSQL ...
+       ...
+...
+```
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/benchmark/Main.hs b/benchmark/Main.hs
new file mode 100644
--- /dev/null
+++ b/benchmark/Main.hs
@@ -0,0 +1,98 @@
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE DataKinds #-}
+{-# LANGUAGE KindSignatures #-}
+
+module Main where
+
+-------------------------------------------------------------------------------
+
+import           Control.Monad.Trans.Reader
+import           Control.Monad.Trans.Class
+import           Criterion.Main
+import           Data.Has
+import           GHC.TypeLits
+
+main :: IO ()
+main = defaultMain
+    [ bgroup "has vs 2 layer reader"
+        [ bench "has" $ whnf (runReader hasReader) (1 :: Int, "hello" :: String)
+        , bench "2 layer" $ whnf (\ (i, s) -> runReader (runReaderT multiReader i) s)
+                                   (1 :: Int, "hello" :: String)
+        ]
+    , bgroup "has vs 8 layer reader"
+        [ bench "has" $ whnf (runReader hasReader8)
+                             ( T 1 :: T 1 Int
+                             , T 2 :: T 2 Int
+                             , T 3 :: T 3 Int
+                             , T 4 :: T 4 Int
+                             , T 5 :: T 5 Int
+                             , T 6 :: T 6 Int
+                             , T 7 :: T 7 Int
+                             , T 8 :: T 8 Int)
+        , bench "8 layer" $ whnf (\ (i1, i2, i3, i4, i5, i6, i7, i8) ->
+                                     runReader
+                                     (runReaderT
+                                     (runReaderT
+                                     (runReaderT
+                                     (runReaderT
+                                     (runReaderT
+                                     (runReaderT
+                                     (runReaderT multiReader8 i1
+                                     ) i2) i3) i4) i5) i6) i7) i8
+                                 ) (1, 2, 3, 4, 5, 6, 7, 8)
+        ]
+    ]
+
+hasReader :: (Has Int r, Has String r) => Reader r String
+hasReader = do
+    i :: Int <- asks get
+    s :: String <- asks get
+    return (s ++ show i)
+
+multiReader :: ReaderT Int (Reader String) String
+multiReader = do
+    i <- ask
+    s <- lift ask
+    return (s ++ show i)
+
+newtype T (a :: Nat) b = T { uT :: b }
+
+hasReader8 :: ( Has (T 1 Int) r
+              , Has (T 2 Int) r
+              , Has (T 3 Int) r
+              , Has (T 4 Int) r
+              , Has (T 5 Int) r
+              , Has (T 6 Int) r
+              , Has (T 7 Int) r
+              , Has (T 8 Int) r
+              ) => Reader r Int
+hasReader8 = do
+    i1 :: T 1 Int <- asks get
+    i2 :: T 2 Int <- asks get
+    i3 :: T 3 Int <- asks get
+    i4 :: T 4 Int <- asks get
+    i5 :: T 5 Int <- asks get
+    i6 :: T 6 Int <- asks get
+    i7 :: T 7 Int <- asks get
+    i8 :: T 8 Int <- asks get
+    return (uT i1 + uT i2 + uT i3 + uT i4 + uT i5 + uT i6 + uT i7 + uT i8)
+
+multiReader8 :: ReaderT Int
+                (ReaderT Int
+                (ReaderT Int
+                (ReaderT Int
+                (ReaderT Int
+                (ReaderT Int
+                (ReaderT Int
+                (Reader Int))))))) Int
+multiReader8 = do
+    i1 <- ask
+    i2 <- lift ask
+    i3 <- lift (lift ask)
+    i4 <- lift (lift (lift ask))
+    i5 <- lift (lift (lift (lift ask)))
+    i6 <- lift (lift (lift (lift (lift ask))))
+    i7 <- lift (lift (lift (lift (lift (lift ask)))))
+    i8 <- lift (lift (lift (lift (lift (lift (lift ask))))))
+    return (i1 + i2 + i3 + i4 + i5 + i6 + i7 + i8)
diff --git a/data-has.cabal b/data-has.cabal
new file mode 100644
--- /dev/null
+++ b/data-has.cabal
@@ -0,0 +1,38 @@
+name:                data-has
+version:             0.1.0.0
+synopsis:            Simple extensible product
+description:         Simple extensible product
+license:             BSD3
+license-file:        LICENSE
+author:              winterland1989
+maintainer:          winterland1989@gmail.com
+-- copyright:           
+category:            Data
+build-type:          Simple
+extra-source-files:  README.md
+cabal-version:       >=1.10
+homepage:           https://github.com/winterland1989/data-has
+
+source-repository head
+  type:     git
+  location: git://github.com/winterland1989/data-has.git
+
+library
+  exposed-modules:      Data.Has
+  -- other-modules:       
+  -- other-extensions:    
+  build-depends:       base < 5
+
+  -- hs-source-dirs:      
+  default-language:    Haskell2010
+
+benchmark bench
+  type: exitcode-stdio-1.0
+  main-is: Main.hs
+  hs-source-dirs: benchmark
+  default-language:    Haskell2010
+  build-depends:        base
+                    ,   data-has
+                    ,   criterion >= 1.0.2.0
+                    ,   transformers
+
