diff --git a/Changelog.md b/Changelog.md
--- a/Changelog.md
+++ b/Changelog.md
@@ -1,3 +1,7 @@
+0.5
+
+- fixed intermittent bug in 'knn', originally due to messing up the order of 'take' and 'sort'.
+
 0.4
 
 - add function to compute the forest construction parameters from the dataset dimensions (rpTreeCfg)
diff --git a/app/Main.hs b/app/Main.hs
--- a/app/Main.hs
+++ b/app/Main.hs
@@ -41,21 +41,21 @@
     chunk = 500
     dim = 2
     -- cfg = rpTreeCfg n dim
-    cfg = RPCfg maxd minl 3 chunk 1.0
-  csvTree0 n cfg
-  tree0dot n cfg
+    cfg = RPCfg maxd chunk 1.0
+  csvTree0 n minl cfg
+  tree0dot n minl cfg
 
 
 
-tree0dot :: Int -> RPTreeConfig -> IO ()
-tree0dot n (RPCfg maxd minl _ chunk _) =
+tree0dot :: Int -> Int -> RPTreeConfig -> IO ()
+tree0dot n minl (RPCfg maxd chunk _) =
   writeDot f fpath "tree0" $ tree0 n maxd minl chunk
   where
     f = show . length
     fpath = "tree0.dot"
 
-csvTree0 :: Int -> RPTreeConfig -> IO ()
-csvTree0 n (RPCfg maxd minl _ chunk _) = do
+csvTree0 :: Int -> Int -> RPTreeConfig -> IO ()
+csvTree0 n minl (RPCfg maxd chunk _) = do
   let
     tt = tree0 n maxd minl chunk
     ttlab = prep tt
diff --git a/rp-tree.cabal b/rp-tree.cabal
--- a/rp-tree.cabal
+++ b/rp-tree.cabal
@@ -1,5 +1,5 @@
 name:                rp-tree
-version:             0.4
+version:             0.5
 synopsis:            Random projection trees
 description:         Random projection trees for approximate nearest neighbor search in high-dimensional vector spaces
                      .
@@ -35,6 +35,7 @@
                      , conduit >= 1.3.1
                      , containers >= 0.6
                      , deepseq >= 1.4
+                     
                      , microlens
                      , microlens-th
                      , mtl >= 2.2.2
@@ -49,6 +50,7 @@
                      -- -- -- DEBUG
                      -- , benchpress
                      -- , hspec
+                     , hspec >= 2.7.1
                      -- , mnist-idx-conduit
                      
 test-suite spec
diff --git a/src/Data/RPTree.hs b/src/Data/RPTree.hs
--- a/src/Data/RPTree.hs
+++ b/src/Data/RPTree.hs
@@ -158,11 +158,13 @@
     -> RPForest d (V.Vector (Embed u d x)) -- ^ random projection forest
     -> v d -- ^ query point
     -> V.Vector (p, Embed u d x) -- ^ ordered in increasing distance order to the query point
-knn distf k tts q = sortByVG fst cs
+knn distf k tts q = VG.take k $ sortByVG fst cs
   where
-    cs = VG.map (\xe -> (eEmbed xe `distf` q, xe)) $ VG.take k $ fold $ (`candidates` q) <$> tts
+    cs = VG.map (\xe -> (eEmbed xe `distf` q, xe)) $ fold $ (`candidates` q) <$> tts
 
--- | Same as 'knn' but with a (hopefully) faster implementation
+-- | Same as 'knn' but accumulating the result in low margin order (following the intuition in 'annoy').
+--
+-- FIXME to be verified
 knnPQ :: (Ord p, Inner SVector v, VU.Unbox d, RealFrac d) =>
          (u d -> v d -> p) -- ^ distance function
       -> Int -- ^ k neighbors
@@ -177,13 +179,21 @@
     n = length tts
 
 
--- | average recall-at-k, computed over a set of trees
-recallWith :: (Inner SVector v, VU.Unbox d, Fractional a1, Ord d, Ord a2, Ord x, Ord (u d), Num d) =>
-              (u d -> v d -> a2)
+-- | Average recall-at-k, computed over a set of trees
+-- 
+-- The supplied distance function @d@ must satisfy the definition of a metric, i.e.
+--
+-- * identity of indiscernible elements : \( d(x, y) = 0 \leftrightarrow x \equiv y \)
+--
+-- * symmetry : \(  d(x, y) = d(y, x)  \)
+--
+-- * triangle inequality : \( d(x, y) + d(y, z) \geq d(x, z) \)
+recallWith :: (Inner SVector v, VU.Unbox d, Fractional b, Ord d, Ord a, Ord x, Ord (u d), Num d) =>
+              (u d -> v d -> a) -- ^ distance function
            -> RPForest d (V.Vector (Embed u d x))
            -> Int -- ^ k : number of nearest neighbors to consider
            -> v d -- ^ query point
-           -> a1
+           -> b
 recallWith distf tt k q = sum rs / fromIntegral n
   where
     rs = fmap (\t -> recallWith1 distf t k q) tt
@@ -197,11 +207,11 @@
            -> p
 recallWith1 distf tt k q = fromIntegral (length aintk) / fromIntegral k
   where
-    xs = points tt
-    dists = sortBy (comparing snd) $ toList $ fmap (\x -> (x, eEmbed x `distf` q)) xs
-    kk = S.fromList $ map fst $ take k dists -- first k nn's
-    aa = set $ candidates tt q
     aintk = aa `S.intersection` kk
+    aa = set $ candidates tt q
+    kk = S.fromList $ map fst $ take k dists -- first k nn's
+    dists = sortBy (comparing snd) $ toList $ fmap (\x -> (x, eEmbed x `distf` q)) xs
+    xs = points tt
 
 set :: (Foldable t, Ord a) => t a -> S.Set a
 set = foldl (flip S.insert) mempty
diff --git a/src/Data/RPTree/Conduit.hs b/src/Data/RPTree/Conduit.hs
--- a/src/Data/RPTree/Conduit.hs
+++ b/src/Data/RPTree/Conduit.hs
@@ -122,25 +122,20 @@
 
 data RPTreeConfig = RPCfg {
   fpMaxTreeDepth :: Int -- ^ max tree depth \(l > 1\) 
-  , fpMinLeafSize :: Int -- ^ min leaf size 
-  , fpNumTrees :: Int -- ^ number of trees \(n_t > 1\)
+  -- , fpMinLeafSize :: Int -- ^ min leaf size 
   , fpDataChunkSize :: Int -- ^ data chunk size
   , fpProjNzDensity :: Double -- ^ nonzero density of projection vectors \(p_{nz} \in (0, 1)\)
                           } deriving (Show)
 
-defaultParams :: RPTreeConfig
-defaultParams = RPCfg 5 10 3 100 0.5
 
--- | Configure the rp-tree forest construction process with some natural defaults
-rpTreeCfg :: Integral a =>
-             a -- ^ data size
-          -> Int -- ^ vector dimension
+-- | Configure the rp-tree tree construction process with some natural defaults
+rpTreeCfg :: Int -- ^ min leaf size
+          -> Int -- ^ number of points in the dataset
+          -> Int -- ^ vector dimension of the data points
           -> RPTreeConfig
-rpTreeCfg n d = RPCfg maxd minl ntree nchunk pnz
+rpTreeCfg minl n d = RPCfg maxd nchunk pnz
   where
-    minl = 10
     maxd = ceiling $ logBase 2 (fromIntegral n / fromIntegral minl)
-    ntree = 3
     nchunk = ceiling $ fromIntegral n / 100
     pnzMin = 1 / logBase 10 (fromIntegral d)
     pnz = pnzMin `min` 1.0
