content: import Data.Foldable (foldl') --'
  import System.Random (randomRs, newStdGen)
  import Control.Monad (zipWithM_)
  import System.Environment (getArgs)
  
  intervals :: [(Double, Double)]
  intervals = map conv [0 .. 9]
    where
      xs = [0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0]
      conv s =
        let [h, l] = take 2 $ drop s xs
        in (h, l)
  
  count :: [Double] -> [Int]
  count rands = map (\iv -> foldl'' (loop iv) 0 rands) intervals
    where
      loop :: (Double, Double) -> Int -> Double -> Int
      loop (lo, hi) n x
        | lo <= x && x < hi = n + 1
        | otherwise = n
  
  -- ^ fuses length and filter within (lo,hi)
  data Pair a b =
    Pair !a
         !b
  
  -- accumulate sum and length in one fold
  sumLen :: [Double] -> Pair Double Double
  sumLen = fion2 . foldl'' (\(Pair s l) x -> Pair (s + x) (l + 1)) (Pair 0.0 0)
    where
      fion2 :: Pair Double Int -> Pair Double Double
      fion2 (Pair s l) = Pair s (fromIntegral l)
  
  -- safe division on pairs
  divl :: Pair Double Double -> Double
  divl (Pair _ 0.0) = 0.0
  divl (Pair s l) = s / l
  
  -- sumLen and divl are separate for stddev below
  mean :: [Double] -> Double
  mean = divl . sumLen
  
  stddev :: [Double] -> Double
  stddev xs = sqrt $ foldl'' (\s x -> s + (x - m) ^ 2) 0 xs / l
    where
      p@(Pair s l) = sumLen xs
      m = divl p
  
  main = do
    nr <- read . head <$> getArgs
    -- or in code, e.g.  let nr = 1000
    rands <- take nr . randomRs (0.0, 1.0) <$> newStdGen
    putStrLn $ "The mean is " ++ show (mean rands) ++ " !"
    putStrLn $ "The standard deviation is " ++ show (stddev rands) ++ " !"
    zipWithM_
      (\iv fq -> putStrLn $ ivstr iv ++ ": " ++ fqstr fq)
      intervals
      (count rands)
    where
      fqstr i =
        replicate
          (if i > 50
             then div i (div i 50)
             else i)
          '*'
      ivstr (lo, hi) = show lo ++ " - " ++ show hi
  
  -- To avoid Wiki formatting issue
  foldl'' = foldl'
  