import System.Random (newStdGen, randomRs) dataBinCounts :: [Float] -> [Float] -> [Int] dataBinCounts thresholds range = zipWith (-) (xs <> [sampleSize]) (0 : xs) where sampleSize = length range xs = (-) sampleSize . length . flip filter range . (<) <$> thresholds --------------------------- TEST ------------------------- main :: IO () main = do g <- newStdGen let fractions = recip <$> [5 .. 11] :: [Float] expected = fractions <> [1 - sum fractions] actual = (/ 1000000.0) . fromIntegral <$> dataBinCounts (scanl1 (+) expected) (take 1000000 (randomRs (0, 1) g)) piv n x = take n (x <> repeat ' '); putStrLn " expected actual" mapM_ putStrLn $ zipWith3 ( \l s c -> piv 7 l <> (piv 13 (show s) <> piv 12 (show c)) ) [ "aleph", "beth", "gimel", "daleth", "he", "waw", "zayin", "heth" ] expected actual