diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,31 @@
+Copyright (c) 2009, Jinjing Wang
+
+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 Jinjing Wang 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/Setup.lhs b/Setup.lhs
new file mode 100644
--- /dev/null
+++ b/Setup.lhs
@@ -0,0 +1,4 @@
+#! /usr/bin/env runhaskell
+
+> import Distribution.Simple
+> main = defaultMain
diff --git a/changelog.md b/changelog.md
new file mode 100644
--- /dev/null
+++ b/changelog.md
diff --git a/monoid-owns.cabal b/monoid-owns.cabal
new file mode 100644
--- /dev/null
+++ b/monoid-owns.cabal
@@ -0,0 +1,22 @@
+Name:                 monoid-owns
+Version:              2010.5.29
+Build-type:           Simple
+Synopsis:             a practical monoid implementation
+Description:          a practical monoid implementation
+
+License:              BSD3
+License-file:         LICENSE
+Author:               Jinjing Wang
+Maintainer:           Jinjing Wang <nfjinjing@gmail.com>
+Build-Depends:        base
+Cabal-version:        >= 1.2
+category:             Web
+homepage:             http://github.com/nfjinjing/monoid-owns
+data-files:           readme.md, changelog.md
+
+library
+  ghc-options: -Wall
+  build-depends: base >= 3 && < 5, containers, bytestring
+  hs-source-dirs: src/
+  exposed-modules:  
+                    Data.Monoid.Owns
diff --git a/readme.md b/readme.md
new file mode 100644
--- /dev/null
+++ b/readme.md
@@ -0,0 +1,4 @@
+Monoid Owns
+===========
+
+A more practical implementation of the monoid class
diff --git a/src/Data/Monoid/Owns.hs b/src/Data/Monoid/Owns.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Monoid/Owns.hs
@@ -0,0 +1,118 @@
+module Data.Monoid.Owns where
+
+import Prelude hiding ((+))
+import qualified Prelude as Prelude
+
+
+import qualified Data.ByteString.Lazy as LB
+import qualified Data.ByteString as B
+
+import qualified Data.Map as Map
+import qualified Data.Set as Set
+import qualified Data.Sequence as Sequence
+
+
+class Monoid a where
+        mempty  :: a
+        -- ^ Identity of 'mappend'
+        mappend :: a -> a -> a
+        -- ^ An associative operation
+        mconcat :: [a] -> a
+
+        -- ^ Fold a list using the monoid.
+        -- For most types, the default definition for 'mconcat' will be
+        -- used, but the function is included in the class definition so
+        -- that an optimized version can be provided for specific types.
+
+        mconcat = foldr mappend mempty
+
+
+(+) :: (Monoid a) => a -> a -> a
+(+) = mappend
+
+infixl 6 +
+
+
+-- Monoid instances.
+
+
+instance Monoid Int where
+  mempty = 0
+  mappend = (Prelude.+)
+
+instance Monoid Integer where
+  mempty = 0
+  mappend = (Prelude.+)
+
+instance Monoid Double where
+  mempty = 0
+  mappend = (Prelude.+)
+
+instance Monoid Float where
+  mempty = 0
+  mappend = (Prelude.+)
+
+
+
+instance Monoid [a] where
+        mempty  = []
+        mappend = (++)
+
+instance Monoid b => Monoid (a -> b) where
+        mempty _ = mempty
+        mappend f g x = f x `mappend` g x
+
+instance Monoid () where
+        -- Should it be strict?
+        mempty        = ()
+        _ `mappend` _ = ()
+        mconcat _     = ()
+
+instance (Monoid a, Monoid b) => Monoid (a,b) where
+        mempty = (mempty, mempty)
+        (a1,b1) `mappend` (a2,b2) =
+                (a1 `mappend` a2, b1 `mappend` b2)
+
+instance (Monoid a, Monoid b, Monoid c) => Monoid (a,b,c) where
+        mempty = (mempty, mempty, mempty)
+        (a1,b1,c1) `mappend` (a2,b2,c2) =
+                (a1 `mappend` a2, b1 `mappend` b2, c1 `mappend` c2)
+
+instance (Monoid a, Monoid b, Monoid c, Monoid d) => Monoid (a,b,c,d) where
+        mempty = (mempty, mempty, mempty, mempty)
+        (a1,b1,c1,d1) `mappend` (a2,b2,c2,d2) =
+                (a1 `mappend` a2, b1 `mappend` b2,
+                 c1 `mappend` c2, d1 `mappend` d2)
+
+instance (Monoid a, Monoid b, Monoid c, Monoid d, Monoid e) =>
+                Monoid (a,b,c,d,e) where
+        mempty = (mempty, mempty, mempty, mempty, mempty)
+        (a1,b1,c1,d1,e1) `mappend` (a2,b2,c2,d2,e2) =
+                (a1 `mappend` a2, b1 `mappend` b2, c1 `mappend` c2,
+                 d1 `mappend` d2, e1 `mappend` e2)
+
+instance Monoid (Maybe a) where
+  mempty = Nothing
+  Nothing `mappend` m = m
+  Just m `mappend` _ = Just m
+
+instance Monoid (B.ByteString) where
+  mempty = B.empty
+  mappend = B.append
+
+instance Monoid (LB.ByteString) where
+  mempty = LB.empty
+  mappend = LB.append
+
+instance (Ord a) => Monoid (Map.Map a b) where
+  mempty = Map.empty
+  mappend = Map.union
+
+instance (Ord a) => Monoid (Set.Set a) where
+  mempty = Set.empty
+  mappend = Set.union
+
+instance Monoid (Sequence.Seq a) where
+  mempty = Sequence.empty
+  mappend = (Sequence.><)
+
