diff --git a/nestedmap.cabal b/nestedmap.cabal
--- a/nestedmap.cabal
+++ b/nestedmap.cabal
@@ -2,11 +2,11 @@
 -- documentation, see http://haskell.org/cabal/users-guide/
 
 name:                nestedmap
-version:             0.1.0.2
+version:             0.1.0.3
 synopsis:            A library for nested maps
 description:         This library supports deeply nested key to value mapping.
-                     Very much like Data.Map, but for heigher, hierarchial dimensions.
-                     It could be used for thing such as markov chains, sparse tensors
+                     Very much like Data.Map, but for higher, hierarchial dimensions.
+                     It could be used for things such as markov chains, sparse tensors
                      or matricies which could contain non-numeric data, file systems, etc.
 license:             BSD3
 license-file:        LICENSE
@@ -23,8 +23,9 @@
   location:            https://github.com/kirstin-rhys/nestedmap
 
 library
-  exposed-modules:     Data.Nested.Tree, Data.Nested.Forest
-  -- other-modules:
+  exposed-modules:     Data.Nested.Tree
+                     , Data.Nested.Forest
+  other-modules:       Data.Nested.Internal
   -- other-extensions:
   hs-source-dirs:      src
   default-language:    Haskell2010
diff --git a/src/Data/Nested/Internal.hs b/src/Data/Nested/Internal.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Nested/Internal.hs
@@ -0,0 +1,199 @@
+{-# LANGUAGE TupleSections #-}
+{-# LANGUAGE GADTs, NoImplicitPrelude, UnicodeSyntax #-}
+
+module Data.Nested.Internal
+       ( -- * Tree and Forest types
+         Tree, Forest
+         -- * Query
+       , fruit, forest, trees, treeAssocs
+       , nullTree, nullForest
+       , sizeTree, sizeForest
+       , lookupTree, lookupForest
+       , memberTree, memberForest                     
+         -- * Construction
+       , emptyTree, emptyForest
+       , singletonTree, singletonForest
+       , fromFoldableTree, fromFoldableForest
+         -- * List
+       , toListForest, toListTree
+       , fromListTree, fromListForest
+       ) where
+
+import qualified Data.List as L
+import Prelude.Unicode ((⊥))
+import Prelude (Num, (+))
+import Data.Maybe (Maybe(Just, Nothing), maybe, isJust)
+import Data.Int (Int)
+import Data.Bool (Bool, otherwise)
+import Data.Ord (Ord)
+import Data.Tuple (uncurry, snd)
+import Data.Function (flip, ($), const, id)
+import Data.Function.Unicode ((∘))
+import Data.Functor (Functor, fmap, (<$>))
+import Data.Foldable (Foldable, foldr, foldMap)
+import Data.Traversable (Traversable, mapAccumL, traverse)
+import Data.Monoid (Monoid, mempty, mappend, mconcat)
+import Data.Monoid.Unicode ((⊕))
+import Text.Show (Show)
+import Control.Arrow ((&&&))
+import Control.Monad (MonadPlus, (>>=), join, return, mplus)
+import Control.Applicative (Applicative)
+import Control.Applicative.Unicode ((⊛))
+import Data.Map (Map)
+import qualified Data.Map as M
+
+data Tree κ α where
+  Tree ∷ { fruit  ∷ α
+         , forest ∷ Forest κ α
+         } → Tree κ α
+  deriving (Show)
+
+data Forest κ α where
+  Forest ∷ { unForest ∷ Map κ (Tree κ α) } → Forest κ α
+  deriving (Show)
+
+instance Functor (Forest κ) where
+  fmap f = Forest ∘ ((f <$>) <$>) ∘ unForest
+
+instance Functor (Tree κ) where
+  fmap f (Tree v ts) = Tree (f v) (f <$> ts)
+
+instance (Ord κ, Monoid α) ⇒ Monoid (Forest κ α) where
+  mempty  = emptyForest
+  mappend = unionForestWith (⊕)
+
+instance (Ord κ, Monoid α) ⇒ Monoid (Tree κ α) where
+  mempty          = Tree mempty mempty
+  t1 `mappend` t2 = Tree (fruit t1 ⊕ fruit t2) (forest t1 ⊕ forest t2)
+
+instance Foldable (Forest κ) where
+  foldMap f = foldMap (foldMap f) ∘ unForest
+  foldr f z = foldr (flip $ foldr f) z ∘ unForest
+
+instance Foldable (Tree κ) where
+  foldMap f             = (f ∘ fruit) ⊕ (foldMap f ∘ forest)
+  foldr f z (Tree v ts) = f v (foldr f z ts)
+
+instance Traversable (Forest κ) where
+  traverse f = (Forest <$>) <$> traverse (traverse f) ∘ unForest 
+
+instance Traversable (Tree κ) where
+  traverse f (Tree v ts) = Tree <$> f v ⊛ traverse f ts
+
+nullForest ∷ Forest κ α → Bool
+nullForest = M.null ∘ unForest
+
+nullTree ∷ Tree κ α → Bool
+nullTree = nullForest ∘ forest
+
+trees ∷ Forest κ α → [Tree κ α]
+trees = M.elems ∘  unForest
+
+treeAssocs ∷ Forest κ α → [(κ, Tree κ α)]
+treeAssocs = M.assocs ∘ unForest
+
+sizeForest ∷ Forest κ α → Int
+sizeForest = foldr (const (+1)) 0
+
+sizeTree ∷ Tree κ α → Int
+sizeTree = (+1) ∘ sizeForest ∘ forest
+
+-- a more general version would use Folable φ as input and a user-specifiable Monoid output
+lookupForest ∷ (Traversable φ, Ord κ) ⇒ Forest κ α → φ κ → φ (Maybe α)
+lookupForest f = snd ∘ mapAccumL (flip lookup) (Just f)
+  where lookup ∷ Ord κ ⇒ κ → Maybe (Forest κ α) → (Maybe (Forest κ α), Maybe α)
+        lookup k = (fmap forest &&& fmap fruit) ∘ join ∘ fmap (M.lookup k ∘ unForest)
+
+lookupTree ∷ (Traversable φ, Ord κ) ⇒ Tree κ α → φ κ → (α, φ (Maybe α))
+lookupTree t = (fruit t,) ∘ lookupForest (forest t)
+
+memberTree ∷ (Traversable φ, Ord κ) ⇒ Tree κ α → φ κ → φ Bool
+memberTree t = (isJust <$>) ∘ snd ∘ lookupTree t 
+
+memberForest ∷ (Traversable φ, Ord κ) ⇒ Forest κ α → φ κ → φ Bool
+memberForest f = (isJust <$>) ∘ lookupForest f
+
+
+emptyForest ∷ Forest κ α
+emptyForest = Forest M.empty
+
+emptyTree ∷ α → Tree κ α
+emptyTree v = Tree v emptyForest
+
+singletonForest ∷ Foldable φ ⇒ φ (κ,α) → Forest κ α
+singletonForest = foldr (uncurry singleton) emptyForest
+  where singleton k v = Forest ∘ M.singleton k ∘ Tree v
+
+singletonTree ∷ Foldable φ ⇒ α → φ (κ,α) → Tree κ α
+singletonTree x = Tree x ∘ singletonForest
+
+fromFoldableForest ∷ (Foldable φ, Foldable ψ, Ord κ) ⇒ ψ (φ (κ, α)) → Forest κ α
+fromFoldableForest = foldr (unionForest ∘ singletonForest)  emptyForest
+
+fromFoldableTree ∷ (Foldable φ, Foldable ψ, Ord κ) ⇒ α → ψ (φ (κ, α)) → Tree κ α
+fromFoldableTree x = Tree x ∘ fromFoldableForest
+
+fromListForest ∷ Ord κ ⇒ [[(κ, α)]] → Forest κ α
+fromListForest = fromFoldableForest
+
+fromListTree ∷ Ord κ ⇒ α → [[(κ, α)]] → Tree κ α
+fromListTree = fromFoldableTree
+
+toListForest ∷ Forest κ α → [[(κ, α)]]
+toListForest = fmap L.reverse ∘ foldrForestWithAncestorsAndLeafMarker leafCons []
+  where leafCons b = if b then (:) else flip const
+
+toListTree ∷ Tree κ α → (α, [[(κ, α)]])
+toListTree t = (fruit t, toListForest (forest t))
+               
+unionForest ∷ Ord κ ⇒ Forest κ α → Forest κ α → Forest κ α
+unionForest (Forest f1) (Forest f2) = Forest $ M.unionWith unionTree f1 f2
+
+unionTree ∷ Ord κ ⇒ Tree κ α → Tree κ α → Tree κ α
+unionTree (Tree _x1 f1) (Tree x2 f2) = Tree x2 (unionForest f1 f2)
+
+unionForestWithKey ∷ Ord κ ⇒ (κ → α → α → α) → Forest κ α → Forest κ α → Forest κ α
+unionForestWithKey f (Forest m1) (Forest m2) = Forest $ M.unionWithKey (unionTreeWithKey' f) m1 m2
+
+unionForestWith ∷ Ord κ ⇒ (α → α → α) → Forest κ α → Forest κ α → Forest κ α
+unionForestWith f = unionForestWithKey (const f)
+
+unionTreeWithKey' ∷ Ord κ ⇒ (κ → α → α → α) → κ → Tree κ α → Tree κ α → Tree κ α
+unionTreeWithKey' f k t1 t2 = Tree (f k (fruit t1) (fruit t2)) (unionForestWithKey f (forest t1) (forest t2))
+
+unionTreeWithKey ∷ Ord κ ⇒ (α → α → α) → (κ → α → α → α) → Tree κ α → Tree κ α → Tree κ α
+unionTreeWithKey g f t1 t2 = Tree (g (fruit t1) (fruit t2)) (unionForestWithKey f (forest t1) (forest t2))
+
+unionTreeWith ∷ Ord κ ⇒ (α → α → α) → Tree κ α → Tree κ α → Tree κ α
+unionTreeWith f = unionTreeWithKey f (const f)
+
+
+
+
+foldrForestWithAncestors ∷ ([(κ, α)] → β → β) → β → Forest κ α → β
+foldrForestWithAncestors f = foldrForestWithAncestors1 f []
+
+foldrForestWithAncestors1 ∷ ([(κ, α)] → β → β) → [(κ, α)] → β → Forest κ α → β
+foldrForestWithAncestors1 f kvs z = M.foldrWithKey (foldrTreeWithAncestors1 f kvs) z ∘ unForest
+
+foldrTreeWithAncestors1 ∷ ([(κ, α)] → β → β) → [(κ, α)] → κ → Tree κ α → β → β
+foldrTreeWithAncestors1 f kvs k t z = f as (foldrForestWithAncestors1 f as z (forest t))
+  where as = (k, fruit t):kvs
+
+
+
+foldrForestWithAncestorsAndLeafMarker ∷ (Bool → [(κ, α)] → β → β) → β → Forest κ α → β
+foldrForestWithAncestorsAndLeafMarker f = foldrForestWithAncestorsAndLeafMarker1 f []
+
+foldrForestWithAncestorsAndLeafMarker1 ∷ (Bool → [(κ, α)] → β → β) → [(κ, α)] → β → Forest κ α → β
+foldrForestWithAncestorsAndLeafMarker1 f kvs z = M.foldrWithKey (foldrTreeWithAncestorsAndLeafMarker1 f kvs) z ∘ unForest
+
+foldrTreeWithAncestorsAndLeafMarker1 ∷ (Bool → [(κ, α)] → β → β) → [(κ, α)] → κ → Tree κ α → β → β
+foldrTreeWithAncestorsAndLeafMarker1 f kvs k t z = f isLeaf as (foldrForestWithAncestorsAndLeafMarker1 f as z (forest t))
+  where as = (k, fruit t):kvs
+        isLeaf = nullTree t
+
+        
+
+
+
