diff --git a/ChangeLog.md b/ChangeLog.md
new file mode 100644
--- /dev/null
+++ b/ChangeLog.md
diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,30 @@
+Copyright (c) 2018, David Millar-Durrant
+
+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 David Millar-Durrant 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.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/indexed-list-literals.cabal b/indexed-list-literals.cabal
new file mode 100644
--- /dev/null
+++ b/indexed-list-literals.cabal
@@ -0,0 +1,76 @@
+-- Initial indexed-container-literals.cabal generated by cabal init.  For 
+-- further documentation, see http://haskell.org/cabal/users-guide/
+
+name:                indexed-list-literals
+version:             0.1.0.0
+synopsis:            Type safe indexed list literals
+homepage:            https://github.com/davidm-d/indexed-list-literals
+license:             BSD3
+license-file:        LICENSE
+author:              David Millar-Durrant
+maintainer:          dmillardurrant@gmail.com
+description:
+  This is an incredibly simple library, which makes writing lists where the length is known at compile time a little bit nicer.
+  .
+  If you write a function with the signature
+  .
+  > vector :: ILL input length output => input -> Vector length output
+  then
+  .
+  > v :: Vector 3 Int
+  > v = vector (1,2,3)
+  >
+  > x :: Vector 0 Double
+  > x = vector $ ZeroTuple @Double
+  >
+  > y :: Vector 1 Double
+  > y = vector (OneTuple 1)
+  >
+  > z :: Vector 2 String
+  > z = vector ("Hello", "World")
+  .
+  If want matrix literals you can write a function
+  .
+  > matrix :: (ILL row width ty, ILL matrix height row) => matrix -> Matrix width height ty
+  then
+  .
+  > a :: Matrix 0 0 Bool
+  > a = matrix $ ZeroTuple @(ZeroTuple Bool)
+  >
+  > b :: Matrix 1 2 String
+  > b = matrix $ OneTuple ("Hello","World")
+  >
+  > c :: Matrix 4 5 Double
+  > c = matrix ((1,2,3,0,0)
+  >            ,(4,5,6,0,0)
+  >            ,(7,8,9,0,0)
+  >            ,(0,0,0,0,0))
+  The full code is in test\/Docs.hs
+  .
+  This only supports literals of length up to 20, though that can be easily extended using the code generator in src\/Data\/IndexedListLiterals.hs
+
+-- copyright:           
+category:            Data
+build-type:          Simple
+extra-source-files:  ChangeLog.md
+cabal-version:       >=1.10
+
+library
+  exposed-modules:     Data.IndexedListLiterals
+  -- other-modules:       
+  -- other-extensions:    
+  build-depends:       base >=4.9 && <= 4.11
+                     , OneTuple >= 0.2.1
+  hs-source-dirs:      src
+  default-language:    Haskell2010
+
+test-suite IndexedListLiterals-test
+            type: exitcode-stdio-1.0
+            main-is: Docs.hs
+            build-depends:       base, indexed-list-literals
+            hs-source-dirs:      test
+            default-language:    Haskell2010
+
+source-repository head
+  type: git
+  location: https://github.com/davidm-d/indexed-list-literals
diff --git a/src/Data/IndexedListLiterals.hs b/src/Data/IndexedListLiterals.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/IndexedListLiterals.hs
@@ -0,0 +1,107 @@
+{-# Language
+  DataKinds,
+  MultiParamTypeClasses,
+  TypeInType,
+  ConstraintKinds,
+  FunctionalDependencies,
+  FlexibleInstances
+  #-}
+module Data.IndexedListLiterals (
+    IndexedListLiterals(..)
+  , ILL
+  , module Data.Tuple.OneTuple
+  , ZeroTuple(..)
+  ) where
+
+import GHC.TypeNats
+import Data.Kind
+import Data.Tuple.OneTuple
+-- import Control.Monad
+
+-- | An alias for IndexedListLiterals
+type ILL = IndexedListLiterals
+
+-- | A type class which allows you to write tuples which can be transformed into a list
+--   the length of the list is also provided as a Nat
+class IndexedListLiterals (input :: Type) (length :: Nat) (output :: Type) | output length -> input, input -> output length where
+  toList :: input -> [output]
+
+instance IndexedListLiterals (ZeroTuple a) 0 a where
+  toList ZeroTuple = []
+
+instance IndexedListLiterals (OneTuple a) 1 a where
+  toList (OneTuple a) = [a]
+
+-- | Intuitively the zero tuple is () or Void but this breaks the Functional Dependency "input -> output length" stopping reliable inference, so this constructor is used to preserve type information
+data ZeroTuple a = ZeroTuple
+
+-- all code generated below comes from this function
+-- generate :: Int -- ^ up to N
+--          -> String
+-- generate n = unlines $ join $ map ("":) $ take n $ dropOneTuple res where
+--   values = map ((:) 'a' . show) [1 :: Int ..]
+--   types  = "a" : types
+--   withCommas = scanl1 (\a b -> a++","++b)
+--   className = "IndexedListLiterals"
+--   template tys vals length =
+--     ["instance " ++ className ++ " (" ++ tys ++ ") " ++ show length ++ " " ++ head types ++ " where"
+--     ,"  toList (" ++ vals ++ ") = [" ++ vals ++ "]"]
+--   res = zipWith3 template (withCommas types) (withCommas values) [0 :: Int ..]
+--   dropOneTuple = tail
+
+instance IndexedListLiterals (a,a) 2 a where
+  toList (a1,a2) = [a1,a2]
+
+instance IndexedListLiterals (a,a,a) 3 a where
+  toList (a1,a2,a3) = [a1,a2,a3]
+
+instance IndexedListLiterals (a,a,a,a) 4 a where
+  toList (a1,a2,a3,a4) = [a1,a2,a3,a4]
+
+instance IndexedListLiterals (a,a,a,a,a) 5 a where
+  toList (a1,a2,a3,a4,a5) = [a1,a2,a3,a4,a5]
+
+instance IndexedListLiterals (a,a,a,a,a,a) 6 a where
+  toList (a1,a2,a3,a4,a5,a6) = [a1,a2,a3,a4,a5,a6]
+
+instance IndexedListLiterals (a,a,a,a,a,a,a) 7 a where
+  toList (a1,a2,a3,a4,a5,a6,a7) = [a1,a2,a3,a4,a5,a6,a7]
+
+instance IndexedListLiterals (a,a,a,a,a,a,a,a) 8 a where
+  toList (a1,a2,a3,a4,a5,a6,a7,a8) = [a1,a2,a3,a4,a5,a6,a7,a8]
+
+instance IndexedListLiterals (a,a,a,a,a,a,a,a,a) 9 a where
+  toList (a1,a2,a3,a4,a5,a6,a7,a8,a9) = [a1,a2,a3,a4,a5,a6,a7,a8,a9]
+
+instance IndexedListLiterals (a,a,a,a,a,a,a,a,a,a) 10 a where
+  toList (a1,a2,a3,a4,a5,a6,a7,a8,a9,a10) = [a1,a2,a3,a4,a5,a6,a7,a8,a9,a10]
+
+instance IndexedListLiterals (a,a,a,a,a,a,a,a,a,a,a) 11 a where
+  toList (a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11) = [a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11]
+
+instance IndexedListLiterals (a,a,a,a,a,a,a,a,a,a,a,a) 12 a where
+  toList (a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12) = [a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12]
+
+instance IndexedListLiterals (a,a,a,a,a,a,a,a,a,a,a,a,a) 13 a where
+  toList (a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13) = [a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13]
+
+instance IndexedListLiterals (a,a,a,a,a,a,a,a,a,a,a,a,a,a) 14 a where
+  toList (a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14) = [a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14]
+
+instance IndexedListLiterals (a,a,a,a,a,a,a,a,a,a,a,a,a,a,a) 15 a where
+  toList (a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15) = [a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15]
+
+instance IndexedListLiterals (a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a) 16 a where
+  toList (a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16) = [a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16]
+
+instance IndexedListLiterals (a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a) 17 a where
+  toList (a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16,a17) = [a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16,a17]
+
+instance IndexedListLiterals (a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a) 18 a where
+  toList (a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16,a17,a18) = [a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16,a17,a18]
+
+instance IndexedListLiterals (a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a) 19 a where
+  toList (a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16,a17,a18,a19) = [a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16,a17,a18,a19]
+
+instance IndexedListLiterals (a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a) 20 a where
+  toList (a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16,a17,a18,a19,a20) = [a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16,a17,a18,a19,a20]
diff --git a/test/Docs.hs b/test/Docs.hs
new file mode 100644
--- /dev/null
+++ b/test/Docs.hs
@@ -0,0 +1,45 @@
+{-# Language TypeApplications, DataKinds, TypeInType, KindSignatures #-}
+
+import Data.IndexedListLiterals
+import GHC.TypeLits
+import Data.Kind
+
+data Matrix (x :: Nat) (y :: Nat) (ty :: Type)
+
+data Vector (length :: Nat) (ty :: Type)
+
+vector :: ILL input length output => input -> Vector length output
+vector = undefined
+
+v :: Vector 3 Int
+v = vector (1,2,3)
+
+x :: Vector 0 Double
+x = vector $ ZeroTuple @Double
+
+y :: Vector 1 Double
+y = vector (OneTuple 1)
+
+z :: Vector 2 String
+z = vector ("Hello", "World")
+
+matrix :: (ILL row width ty, ILL matrix height row) => matrix -> Matrix height width ty
+matrix = undefined
+
+a :: Matrix 0 0 Bool
+a = matrix $ ZeroTuple @(ZeroTuple Bool)
+
+b :: Matrix 1 2 String
+b = matrix $ OneTuple ("Hello","World")
+
+c :: Matrix 4 5 Double
+c = matrix ((1,2,3,0,0)
+           ,(4,5,6,0,0)
+           ,(7,8,9,0,0)
+           ,(0,0,0,0,0))
+
+-- | just making sure the docs type check
+main :: IO ()
+main = do
+  _ <- return (a,b,c,v,x,y,z)
+  return ()
