diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,20 @@
+Copyright (c) 2015 Douglas McClean
+
+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/README.md b/README.md
new file mode 100644
--- /dev/null
+++ b/README.md
@@ -0,0 +1,2 @@
+# exact-pi
+Exact rational multiples of pi (and integer powers of pi) in Haskell
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/exact-pi.cabal b/exact-pi.cabal
new file mode 100644
--- /dev/null
+++ b/exact-pi.cabal
@@ -0,0 +1,32 @@
+-- Initial exact-pi.cabal generated by cabal init.  For further 
+-- documentation, see http://haskell.org/cabal/users-guide/
+
+name:                exact-pi
+version:             0.1.0.0
+synopsis:            Exact rational multiples of pi (and integer powers of pi)
+description:         Provides an exact representation for rational multiples of pi alongside an approximate representation of all reals.
+                     Useful for storing and computing with conversion factors between physical units.
+homepage:            https://github.com/dmcclean/exact-pi
+license:             MIT
+license-file:        LICENSE
+author:              Douglas McClean
+maintainer:          douglas.mcclean@gmail.com
+-- copyright:           
+category:            Data
+build-type:          Simple
+extra-source-files:  README.md
+cabal-version:       >=1.10
+
+library
+  exposed-modules:     Data.ExactPi
+  -- other-modules:       
+  -- other-extensions:    
+  build-depends:       base >=4.8 && <4.9,
+                       groups >= 0.4 && < 0.5
+  hs-source-dirs:      src
+  default-language:    Haskell2010
+
+source-repository head
+  type:                git
+  location:            https://github.com/dmcclean/exact-pi.git
+  
diff --git a/src/Data/ExactPi.hs b/src/Data/ExactPi.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/ExactPi.hs
@@ -0,0 +1,101 @@
+{-# LANGUAGE RankNTypes #-}
+
+{-# OPTIONS_HADDOCK show-extensions #-}
+
+{-|
+Module      : Kaos.Math.AugmentedRational
+Description : Exact rational multiples of powers of pi
+License     : MIT
+Maintainer  : douglas.mcclean@gmail.com
+Stability   : experimental
+
+This type is sufficient to exactly express the closure of Q ∪ {π} under multiplication and division.
+As a result it is useful for representing conversion factors
+between physical units. Approximate values are included both to close the remainder
+of the arithmetic operations in the `Num` typeclass and to encode conversion
+factors defined experimentally.
+-}
+module Data.ExactPi
+(
+  ExactPi(..),
+  approximateValue,
+  isExactZero
+)
+where
+
+import Data.Group
+
+-- | Represents an exact or approximate real value.
+-- The exactly representable values are rational multiples of an integer power of pi.
+data ExactPi = Exact Integer Rational -- ^ @'Exact' z q@ = q * pi^z. Note that this means there are many representations of zero.
+             | Approximate (forall a.Floating a => a) -- ^ An approximate value. This representation was chosen because it allows conversion to floating types using their native definition of 'pi'.
+
+-- | Approximates an exact or approximate value, converting it to a `Floating` type.
+-- This uses the value of `pi` supplied by the destination type, to provide the appropriate
+-- precision.
+approximateValue :: Floating a => ExactPi -> a
+approximateValue (Exact z q) = (pi ^ z) * (fromRational q)
+approximateValue (Approximate x) = x
+
+-- | Identifies whether an 'ExactPi' is an exact representation of zero.
+isExactZero :: ExactPi -> Bool
+isExactZero (Exact _ 0) = True
+isExactZero _ = False
+
+instance Show ExactPi where
+  show (Exact z q) | z == 0 = "Exactly " ++ show q
+                   | z == 1 = "Exactly pi * " ++ show q
+                   | otherwise = "Exactly pi^" ++ show z ++ " * " ++ show q
+  show (Approximate x) = "Approximately " ++ show (x :: Double)
+
+instance Num ExactPi where
+  fromInteger n = Exact 0 (fromInteger n)
+  (Exact z1 q1) * (Exact z2 q2) = Exact (z1 + z2) (q1 * q2)
+  (Exact _ 0) * _ = 0
+  _ * (Exact _ 0) = 0
+  x * y = Approximate $ approximateValue x * approximateValue y
+  (Exact z1 q1) + (Exact z2 q2) | z1 == z2 = Exact z1 (q1 + q2) -- by distributive property
+  x + y = Approximate $ approximateValue x + approximateValue y
+  abs (Exact z q) = Exact z (abs q)
+  abs (Approximate x) = Approximate $ abs x
+  signum (Exact _ q) = Exact 0 (signum q)
+  signum (Approximate x) = Approximate $ signum x -- we leave this tagged as approximate because we don't know "how" approximate the input was. a case could be made for exact answers here.
+  negate x = (-1) * x
+
+instance Fractional ExactPi where
+  fromRational = Exact 0
+  recip (Exact z q) = Exact z (recip q)
+
+instance Floating ExactPi where
+  pi = Exact 1 1
+  exp x | isExactZero x = 1
+        | otherwise = approx1 exp x
+  log (Exact 0 1) = 0
+  log x = approx1 log x
+  -- It would be possible to give tighter bounds to the trig functions, preserving exactness for arguments that have an exactly representable result.
+  sin = approx1 sin
+  cos = approx1 cos
+  tan = approx1 tan
+  asin = approx1 asin
+  atan = approx1 atan
+  acos = approx1 acos
+  sinh = approx1 sinh
+  cosh = approx1 cosh
+  tanh = approx1 tanh
+  asinh = approx1 asinh
+  acosh = approx1 acosh
+  atanh = approx1 atanh
+
+approx1 :: (forall a.Floating a => a -> a) -> ExactPi -> ExactPi
+approx1 f x = Approximate (f (approximateValue x))
+
+-- | The multiplicative monoid over augmented rationals.
+instance Monoid ExactPi where
+  mempty = 1
+  mappend = (*)
+
+-- | The multiplicative group over augmented rationals.
+instance Group ExactPi where
+  invert = recip
+
+instance Abelian ExactPi
