diff --git a/Data/KMeans.hs b/Data/KMeans.hs
new file mode 100644
--- /dev/null
+++ b/Data/KMeans.hs
@@ -0,0 +1,40 @@
+module Data.KMeans (kmeans, kmeans')
+    where
+
+import Data.List (transpose, sort, groupBy, minimumBy)
+import Data.Function (on)
+import Data.Ord (comparing)
+
+type Vector a = [a]
+
+dist a b = sqrt . sum $ zipWith (\x y-> (x-y) ^ 2) a b
+
+centroid points = map (flip (/) l . sum) $ transpose points
+    where l = fromIntegral $ length points
+
+closest points point = minimumBy (comparing $ dist point) points
+
+recluster' centroids points = map (map snd) $ groupBy ((==) `on` fst) reclustered
+    where reclustered = sort [(closest centroids a, a) | a <- points]
+
+recluster clusters = recluster' centroids $ concat clusters
+    where centroids = map centroid clusters
+
+part x ys
+     | zs' == [] = [zs]
+     | otherwise = zs : part x zs'
+    where (zs, zs') = splitAt x ys
+
+-- | Recluster points
+kmeans' :: (Floating a, Ord a) => [[Vector a]] -> [[Vector a]]
+kmeans' clusters
+    | clusters == clusters' = clusters
+    | otherwise             = kmeans' clusters'
+    where clusters' = recluster clusters
+
+-- | Cluster points into k clusters.
+-- |
+-- | The initial clusters are chosen arbitrarily
+kmeans :: (Floating a, Ord a) => Int -> [Vector a] -> [[Vector a]]
+kmeans k points = kmeans' $ part l points
+    where l = (length points + k - 1) `div` k
diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,30 @@
+Copyright (c) Keegan Carruthers-Smith
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+1. Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+
+2. 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.
+
+3. Neither the name of the author nor the names of his contributors
+   may be used to endorse or promote products derived from this software
+   without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE 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 AUTHORS 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/kmeans.cabal b/kmeans.cabal
new file mode 100644
--- /dev/null
+++ b/kmeans.cabal
@@ -0,0 +1,19 @@
+Name:               kmeans
+Version:            0.1
+Description:
+    A simple library for k-means clustering
+Category:           algorithms, clustering, data mining
+Synopsis:           Hidden Markov Model algorithms
+License:            BSD3
+License-file:       LICENSE
+Author:             Keegan Carruthers-Smith
+Maintainer:         max.rabkin@gmail.com
+Stability:          Alpha
+Build-Type:         Simple
+Cabal-Version:      >= 1.2
+
+Library
+    Build-Depends:  base >= 3 && < 5
+
+    Exposed-Modules:
+        Data.KMeans
