diff --git a/HLearn-distributions.cabal b/HLearn-distributions.cabal
--- a/HLearn-distributions.cabal
+++ b/HLearn-distributions.cabal
@@ -1,5 +1,5 @@
 Name:                HLearn-distributions
-Version:             0.1.0.0
+Version:             0.1.0.1
 Synopsis:            Distributions for use with the HLearn library
 Description:         This module is used to estimate statistical distributions from data.  The focus is a clean interface inspired by algebra.
 Category:            Data Mining, Machine Learning, Statistics
@@ -69,7 +69,9 @@
         
         -- are these really necessary?
         process                 >= 1.1.0.2,
-        MonadRandom             >= 0.1.6
+        MonadRandom             >= 0.1.6,
+        math-functions          >= 0.1.1,
+        normaldistribution      >= 1.1.0
 
         
     hs-source-dirs:     src
@@ -86,6 +88,7 @@
         HLearn.Models.Distributions.Common
         HLearn.Models.Distributions.Categorical
         HLearn.Models.Distributions.KernelDensityEstimator
+        HLearn.Models.Distributions.KernelDensityEstimator.Kernels
         HLearn.Models.Distributions.Moments
         --HLearn.Models.Distributions.Normal
         --HLearn.Models.Distributions.Gaussian
diff --git a/src/HLearn/Gnuplot/Distributions.hs b/src/HLearn/Gnuplot/Distributions.hs
--- a/src/HLearn/Gnuplot/Distributions.hs
+++ b/src/HLearn/Gnuplot/Distributions.hs
@@ -2,6 +2,8 @@
 {-# LANGUAGE FlexibleInstances #-}
 {-# LANGUAGE TypeSynonymInstances #-}
 
+-- | This file contains the functions for plotting distributions using Gnuplot.  The interface is still under heavy construction, so it's not very well documented as of yet.
+
 module HLearn.Gnuplot.Distributions
     where
 
diff --git a/src/HLearn/Models/Distributions.hs b/src/HLearn/Models/Distributions.hs
--- a/src/HLearn/Models/Distributions.hs
+++ b/src/HLearn/Models/Distributions.hs
@@ -3,51 +3,19 @@
 {-# LANGUAGE MultiParamTypeClasses #-}
 {-# LANGUAGE UndecidableInstances #-}
 
+-- | This file exports the most commonly used modules within HLearn-distributions.  Most likely this is the only file you will have to import.
+
 module HLearn.Models.Distributions
     ( module HLearn.Models.Distributions.Common
     , module HLearn.Models.Distributions.Categorical
-    , module HLearn.Models.Distributions.KernelDensityEstimator
 --     , module HLearn.Models.Distributions.Gaussian
+    , module HLearn.Models.Distributions.KernelDensityEstimator
+    , module HLearn.Models.Distributions.Moments
     )
     where
 
 import HLearn.Models.Distributions.Common
 import HLearn.Models.Distributions.Categorical
-import HLearn.Models.Distributions.KernelDensityEstimator
 -- import HLearn.Models.Distributions.Gaussian
--- import HLearn.DataContainers
--- import HLearn.Math.TypeClasses
-
-import qualified Data.Map as Map
-import Debug.Trace
-import Data.List.Extras
-
--------------------------------------------------------------------------------
--- Training
-
--- instance (OnlineTrainer CategoricalParams (Categorical label) datatype label) => 
---     BatchTrainer CategoricalParams (Categorical label) datatype label 
---         where
---               
---     trainBatch = trainOnline
--- 
--- instance (Label label) => EmptyTrainer CategoricalParams (Categorical label) label where
---     emptyModel desc modelparams = Categorical Map.empty (Just desc)
--- 
--- instance (Label label) => OnlineTrainer CategoricalParams (Categorical label) datatype label where
---     add1dp desc modelparams model dps = return $ add1sample model $ fst dps
--- 
--- -------------------------------------------------------------------------------
--- -- Classification
--- 
--- instance (Label label) => Classifier (Categorical label) datatype label where
---     classify model dp = mean model --fst $ argmaxBy compare snd $ probabilityClassify model dp
--- 
--- instance (Label label) => ProbabilityClassifier (Categorical label) datatype label where
---     probabilityClassify model dp = model--trace "CategoricalPC" $
--- --         case Map.keys $ pdfmap model of
--- --             [] -> trace "WARNING: ProbabilityClassifier: empty Categorical" $ 
--- --                 case desc model of
--- --                     Nothing -> error "probabilityClassify: empty Categorical and empty DataDesc"
--- --                     Just desc -> map (\label -> (label,1/(fromIntegral $ numLabels desc))) $ labelL desc
--- --             xs -> map (\k -> (k,pdf model k)) xs
+import HLearn.Models.Distributions.KernelDensityEstimator
+import HLearn.Models.Distributions.Moments
diff --git a/src/HLearn/Models/Distributions/Categorical.hs b/src/HLearn/Models/Distributions/Categorical.hs
--- a/src/HLearn/Models/Distributions/Categorical.hs
+++ b/src/HLearn/Models/Distributions/Categorical.hs
@@ -5,9 +5,15 @@
 {-# LANGUAGE ScopedTypeVariables #-}
 {-# LANGUAGE BangPatterns #-}
 
+
+-- | The categorical distribution is used for discrete data.  It is also sometimes called the discrete distribution or the multinomial distribution.  For more, see the wikipedia entry: <https://en.wikipedia.org/wiki/Categorical_distribution>
 module HLearn.Models.Distributions.Categorical
-    ( Categorical (..)
+    ( 
+    -- * Data types
+    Categorical (..)
     , CategoricalParams(..)
+    
+    -- * Helper functions
     , dist2list
     , mostLikely
     )
@@ -50,8 +56,6 @@
         } 
     deriving (Show,Read,Eq,Ord)
 
-dist2list :: Categorical sampletype probtype -> [(sampletype,probtype)]
-dist2list (Categorical pdfmap) = Map.toList pdfmap
 
 instance (NFData sampletype, NFData probtype) => NFData (Categorical sampletype probtype) where
     rnf d = rnf $ pdfmap d
@@ -98,9 +102,13 @@
         return $ cdfInverse dist (x::prob)
 -}
 
+-- | Extracts the element in the distribution with the highest probability
 mostLikely :: Ord prob => Categorical label prob -> label
 mostLikely dist = fst $ argmax snd $ Map.toList $ pdfmap dist
 
+-- | Converts a distribution into a list of (sample,probability) pai
+dist2list :: Categorical sampletype probtype -> [(sampletype,probtype)]
+dist2list (Categorical pdfmap) = Map.toList pdfmap
 
 -------------------------------------------------------------------------------
 -- Algebra
diff --git a/src/HLearn/Models/Distributions/KernelDensityEstimator.hs b/src/HLearn/Models/Distributions/KernelDensityEstimator.hs
--- a/src/HLearn/Models/Distributions/KernelDensityEstimator.hs
+++ b/src/HLearn/Models/Distributions/KernelDensityEstimator.hs
@@ -11,36 +11,38 @@
 
 {-# LANGUAGE DataKinds #-}
 
+-- | Kernel Density Estimation (KDE) is a generic and powerful method for estimating a probability distribution.  See wikipedia for more information: <http://en.wikipedia.org/wiki/Kernel_density_estimation>
 module HLearn.Models.Distributions.KernelDensityEstimator
-    ( KDEParams (..)
+    ( 
+    -- * Parameters
+    KDEParams (..)
     , KDEBandwidth (..)
+    
+    -- * Data types
     , KDE (..)
     , KDE' (..)
+    
+    -- * Easy creation of parameters
     , genSamplePoints
     
-    , Uniform (..)
-    , Triangular (..)
-    , Epanechnikov (..)
-    , Quartic (..)
-    , Triweight (..)
-    , Tricube (..)
-    , Gaussian (..)
-    , Cosine (..)
-    , KernelBox (..)
+    , module HLearn.Models.Distributions.KernelDensityEstimator.Kernels
     )
     where
           
 import HLearn.Algebra
 import HLearn.Models.Distributions.Common
 import HLearn.Models.Distributions.Categorical
+import HLearn.Models.Distributions.KernelDensityEstimator.Kernels
 
 import qualified Control.ConstraintKinds as CK
 import Control.DeepSeq
 import qualified Data.Vector.Unboxed as VU
 
 -------------------------------------------------------------------------------
---
+-- Parameters
 
+-- | The bandwidth is a \"free parameter\" that has a large influence on the resulting PDF.  The simplest way to set the bandwidth is using a constant.  However, we can also have a bandwidth that varies over the domain of the distribution.  This is done using the Variable constructor.  For more, see Wikipedia's entry on Variable KDE: <https://en.wikipedia.org/wiki/Variable_kernel_density_estimation>.
+
 data KDEBandwidth prob = Constant prob | Variable (prob -> prob)
 
 instance (Show prob) => Show (KDEBandwidth prob) where
@@ -79,7 +81,15 @@
                   $ seq (samplePoints kdeparams)
                   $ ()
 
-genSamplePoints :: (Fractional prob, VU.Unbox prob) => Int -> Int -> Int -> VU.Vector prob
+
+-- | Generates a vector of the positions to sample our distribution at to generate the PDF.  It is intended for use with KDEParams only.
+genSamplePoints :: 
+    ( Fractional prob
+    , VU.Unbox prob
+    ) => Int -- minimum point
+      -> Int -- maximum point
+      -> Int -- number of samples
+      -> VU.Vector prob
 genSamplePoints min max samples = VU.fromList $ map (\i -> (fromIntegral min) + (fromIntegral i)*step) [0..samples]
     where
         step = (fromIntegral $ max-min)/(fromIntegral $ samples)
@@ -98,6 +108,10 @@
 --         n = fromIntegral $ length xs
 --         sigma = 1
 
+-------------------------------------------------------------------------------
+-- KDE
+
+-- | This is an intermediate data structure used by the KDE data type.  You should NEVER use it directly because it doesn't have an empty element.  It is exported because some other modules in the HLearn library need direct access to it.
 data KDE' prob = KDE'
     { params :: KDEParams prob
     , n :: prob
@@ -111,6 +125,7 @@
             $ seq (sampleVals kde)
             $ ()
 
+-- | The data structure that stores our Kernel Density Estimate.  Because KDE' doesn't have an empty element, we use the RegSG2Group free structure to provide one for us.  KDE inherits all the instances of KDE', plus Monoid and Group instances.
 type KDE prob = RegSG2Group (KDE' prob)
 
 -------------------------------------------------------------------------------
@@ -190,68 +205,3 @@
 instance Morphism (Categorical Int Double) (KDEParams Double) (KDE Double) where
     cat $> kdeparams = train' kdeparams $ CK.fmap (fromIntegral :: Int -> Double) (cat $> FreeModParams)
 
--------------------------------------------------------------------------------
--- Kernels
-
--- | This list of kernels is take from wikipedia's: https://en.wikipedia.org/wiki/Uniform_kernel#Kernel_functions_in_common_use
-class Kernel kernel num where
-    evalkernel :: kernel -> num -> num
-
-data KernelBox num where KernelBox :: (Kernel kernel num, Show kernel) => kernel -> KernelBox num
-
-instance Kernel (KernelBox num) num where
-    evalkernel (KernelBox k) p = evalkernel k p
-instance Show (KernelBox num) where
-    show (KernelBox k) = "KB "++show k
-instance Eq (KernelBox num) where
-    KernelBox k1 == KernelBox k2 = (show k1) == (show k2)
-instance Ord (KernelBox num) where
-    _ `compare` _ = EQ
-instance NFData (KernelBox num) where
-    rnf (KernelBox num)= seq num ()
-    
-data Uniform = Uniform deriving (Read,Show)
-instance (Fractional num, Ord num) => Kernel Uniform num where
-    evalkernel Uniform u = if abs u < 1
-        then 1/2
-        else 0
-
-data Triangular = Triangular deriving (Read,Show)
-instance (Fractional num, Ord num) => Kernel Triangular num where
-    evalkernel Triangular u = if abs u<1
-        then 1-abs u
-        else 0
-        
-data Epanechnikov = Epanechnikov deriving (Read,Show)
-instance (Fractional num, Ord num) => Kernel Epanechnikov num where
-    evalkernel Epanechnikov u = if abs u<1
-        then (3/4)*(1-u^^2)
-        else 0
-
-data Quartic = Quartic deriving (Read,Show)
-instance (Fractional num, Ord num) => Kernel Quartic num where
-    evalkernel Quartic u = if abs u<1
-        then (15/16)*(1-u^^2)^^2
-        else 0
-        
-data Triweight = Triweight deriving (Read,Show)
-instance (Fractional num, Ord num) => Kernel Triweight num where
-    evalkernel Triweight u = if abs u<1
-        then (35/32)*(1-u^^2)^^3
-        else 0
-
-data Tricube = Tricube deriving (Read,Show)
-instance (Fractional num, Ord num) => Kernel Tricube num where
-    evalkernel Tricube u = if abs u<1
-        then (70/81)*(1-u^^3)^^3
-        else 0
-        
-data Cosine = Cosine deriving (Read,Show)
-instance (Floating num, Ord num) => Kernel Cosine num where
-    evalkernel Cosine u = if abs u<1
-        then (pi/4)*(cos $ (pi/2)*u)
-        else 0
-        
-data Gaussian = Gaussian deriving (Read,Show)
-instance (Floating num, Ord num) => Kernel Gaussian num where
-    evalkernel Gaussian u = (1/(2*pi))*(exp $ (-1/2)*u^^2)
diff --git a/src/HLearn/Models/Distributions/KernelDensityEstimator/Kernels.hs b/src/HLearn/Models/Distributions/KernelDensityEstimator/Kernels.hs
new file mode 100644
--- /dev/null
+++ b/src/HLearn/Models/Distributions/KernelDensityEstimator/Kernels.hs
@@ -0,0 +1,89 @@
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE GADTs #-}
+{-# LANGUAGE FlexibleInstances #-}
+   
+-- | This list of kernels is take from wikipedia's: <https://en.wikipedia.org/wiki/Uniform_kernel#Kernel_functions_in_common_use>
+module HLearn.Models.Distributions.KernelDensityEstimator.Kernels
+    (
+    -- * Data types
+    Kernel (..)
+    , KernelBox (..)
+    
+    -- * Kernels
+    , Uniform (..)
+    , Triangular (..)
+    , Epanechnikov (..)
+    , Quartic (..)
+    , Triweight (..)
+    , Tricube (..)
+    , Gaussian (..)
+    , Cosine (..)
+    
+    )
+    where
+   
+import Control.DeepSeq
+
+-- | A kernel is function in one parameter that takes a value on the x axis and spits out a "probability."  We create a data object for each kernel, and a corresponding class to make things play nice with the type system.
+class Kernel kernel num where
+    evalkernel :: kernel -> num -> num
+
+-- | A KernelBox is a universal object for storing kernels.  Whatever kernel it stores, it becomes a kernel with the same properties.
+data KernelBox num where KernelBox :: (Kernel kernel num, Show kernel) => kernel -> KernelBox num
+
+instance Kernel (KernelBox num) num where
+    evalkernel (KernelBox k) p = evalkernel k p
+instance Show (KernelBox num) where
+    show (KernelBox k) = "KB "++show k
+instance Eq (KernelBox num) where
+    KernelBox k1 == KernelBox k2 = (show k1) == (show k2)
+instance Ord (KernelBox num) where
+    _ `compare` _ = EQ
+instance NFData (KernelBox num) where
+    rnf (KernelBox num)= seq num ()
+    
+data Uniform = Uniform deriving (Read,Show)
+instance (Fractional num, Ord num) => Kernel Uniform num where
+    evalkernel Uniform u = if abs u < 1
+        then 1/2
+        else 0
+
+data Triangular = Triangular deriving (Read,Show)
+instance (Fractional num, Ord num) => Kernel Triangular num where
+    evalkernel Triangular u = if abs u<1
+        then 1-abs u
+        else 0
+        
+data Epanechnikov = Epanechnikov deriving (Read,Show)
+instance (Fractional num, Ord num) => Kernel Epanechnikov num where
+    evalkernel Epanechnikov u = if abs u<1
+        then (3/4)*(1-u^^2)
+        else 0
+
+data Quartic = Quartic deriving (Read,Show)
+instance (Fractional num, Ord num) => Kernel Quartic num where
+    evalkernel Quartic u = if abs u<1
+        then (15/16)*(1-u^^2)^^2
+        else 0
+        
+data Triweight = Triweight deriving (Read,Show)
+instance (Fractional num, Ord num) => Kernel Triweight num where
+    evalkernel Triweight u = if abs u<1
+        then (35/32)*(1-u^^2)^^3
+        else 0
+
+data Tricube = Tricube deriving (Read,Show)
+instance (Fractional num, Ord num) => Kernel Tricube num where
+    evalkernel Tricube u = if abs u<1
+        then (70/81)*(1-u^^3)^^3
+        else 0
+        
+data Cosine = Cosine deriving (Read,Show)
+instance (Floating num, Ord num) => Kernel Cosine num where
+    evalkernel Cosine u = if abs u<1
+        then (pi/4)*(cos $ (pi/2)*u)
+        else 0
+        
+data Gaussian = Gaussian deriving (Read,Show)
+instance (Floating num, Ord num) => Kernel Gaussian num where
+    evalkernel Gaussian u = (1/(2*pi))*(exp $ (-1/2)*u^^2)
diff --git a/src/HLearn/Models/Distributions/Moments.hs b/src/HLearn/Models/Distributions/Moments.hs
--- a/src/HLearn/Models/Distributions/Moments.hs
+++ b/src/HLearn/Models/Distributions/Moments.hs
@@ -13,6 +13,8 @@
 {-# LANGUAGE DatatypeContexts #-}
 {-# LANGUAGE NoMonomorphismRestriction #-}
 
+-- | The method of moments can be used to estimate a number of commonly used distributions.  This module is still under construction as I work out the best way to handle morphisms from the Moments type to types of other distributions.  For more information, see the wikipedia entry: <https://en.wikipedia.org/wiki/Method_of_moments_(statistics)>
+
 module HLearn.Models.Distributions.Moments
     ( MomentsParams (..)
     , Moments (..)
