diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,20 @@
+Copyright (c) 2015 Tobias Dammers
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
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/data-tensor.cabal b/data-tensor.cabal
new file mode 100644
--- /dev/null
+++ b/data-tensor.cabal
@@ -0,0 +1,23 @@
+name:                data-tensor
+version:             0.1.0.0
+synopsis:            Tensor and Group typeclasses
+description:         Typeclasses for Groups (Monoids with an 'invert'
+                     operation) and Tensors.
+homepage:            https://bitbucket.org/tdammers/data-tensor
+license:             MIT
+license-file:        LICENSE
+author:              Tobias Dammers
+maintainer:          tdammers@gmail.com
+copyright:           2015
+category:            Data
+build-type:          Simple
+-- extra-source-files:
+cabal-version:       >=1.10
+
+library
+  exposed-modules:     Data.Tensor
+  -- other-modules:
+  -- other-extensions:
+  build-depends:       base >=4.5 && <5.0
+  hs-source-dirs:      src
+  default-language:    Haskell2010
diff --git a/src/Data/Tensor.hs b/src/Data/Tensor.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Tensor.hs
@@ -0,0 +1,72 @@
+{-#LANGUAGE MultiParamTypeClasses #-}
+{-#LANGUAGE FlexibleInstances #-}
+-- | Typeclasses for Group and Tensor, extending 'Monoid'.
+module Data.Tensor
+( module Data.Monoid
+, Group (..)
+, Tensor (..)
+)
+where
+
+import Data.Monoid
+
+-- | A group is a monoid with an invert operation.
+-- Intuition: '><' is to '<>' what subtraction is to addition; 'invert' turns a
+-- value into its complement (see Laws below), and corresponds with unary minus
+-- in addition.
+--
+-- Laws:
+--
+-- > a >< b == a <> (invert b)
+-- > a >< mempty == a
+-- > a >< a == mempty
+-- > a <> (invert a) == mempty
+-- > invert mempty == mempty
+--
+class Monoid a => Group a where
+    -- | Dual to '<>'.
+    (><) :: a -> a -> a
+    a >< b = a <> invert b
+    -- | \"Negation\": convert an operand into its dual.
+    invert :: a -> a
+    invert x = mempty >< x
+
+infixl 6 ><
+
+instance Num a => Group (Sum a) where
+    invert = Sum . negate . getSum
+
+-- | Tensor allows us to define a relationship between two types, the second
+-- one forming a Group.
+-- The intuition is that the first type models something like a
+-- "location", and the second (the group) models the relative distance between
+-- two locations. Examples of Tensors include date/time values (point in time)
+-- and timespans; positions in a vector space and displacement vectors;
+-- pitches and intervals in music.
+--
+-- Tensor provides three operations: '?<>' (\"tensor addition\"), adding a
+-- \"distance\" to a \"location\"; '?><' (\"tensor subtraction\"), undoing the effect
+-- of adding a \"distance\" to a \"location\", and '>?<', getting the \"distance\"
+-- between two \"locations\".
+--
+-- Laws:
+--
+-- > a ?<> (b >?< a) == b
+-- > a ?<> (x <> y) == a ?<> x ?<> y
+-- > a ?>< b == a ?<> (invert b)
+-- > a ?<> (x >< y) == a ?<> x ?>< y
+class Group b => Tensor a b where
+    (?<>) :: a -> b -> a
+    (?><) :: a -> b -> a
+    (>?<) :: a -> a -> b
+    a ?>< b = a ?<> invert b
+
+infixl 6 ?<>
+infixl 6 ?><
+infixl 6 >?<
+
+-- | All groups trivially form tensors with themselves
+instance Group a => Tensor a a where
+    (?<>) = (<>)
+    (?><) = (><)
+    (>?<) = (><)
