This is a tiny etude on a theme given here, using Python: Provide a function that generates a human readable file size such as
42.2TiB from a given integer number. (A similar Ruby etude is here.) The function should
- gracefully handle any input (even negative numbers, although they don't make sense for counting bytes - maybe they could represent negative offsets)
- print numbers smaller than 1024 without a decimal point
- print all other numbers with one decimal place and the appropriate unit (KiB, MiB, etc.)
It's more verbose than the python counterpart, so the question is whether this can be made more terse.
humanReadableBytes :: Integer -> String humanReadableBytes size | null pairs = printf "%.0fZiB" (size'/1024^7) | otherwise = if unit=="" then printf "%dB" size else printf "%.1f%sB" n unit where (n, unit) = head pairs pairs = dropWhile ((1024<).abs.fst) (zip (map ((size'/).(1024^)) [0..]) units) :: [(Double, String)] size' = fromIntegral size units = ["","Ki","Mi","Gi","Ti","Pi","Ei","Zi"]
Right away it can be noted that the use of
String is suboptimal, but
Text.Printf does not allow
printf ought to be replaced.