Reputation: 161
Is there a library function to put commas into numbers with Haskell?
I want a function that would work something like this:
format 1000000 = "1,000,000"
format 1045.31 = "1,045.31"
but I can't seem to find any number formatting functions of this type in Haskell. Where are the number formatting functions?
Upvotes: 16
Views: 3643
Reputation: 33861
Using the format-numbers library
Prelude> import Data.Text.Format.Numbers
Prelude Data.Text.Format.Numbers> prettyF (PrettyCfg 2 (Just ',') '.') 2132871293.3412
"2,132,871,293.34"
Upvotes: 4
Reputation: 7182
Another solution that I'm using:
thousands :: Double -> Text
thousands d = T.intercalate "." $ case T.splitOn "." (T.pack (show d)) of
x:xs -> (T.pack . reverse . go . reverse . T.unpack) x : xs
xs -> xs
where
go (x:y:z:[]) = x:y:z:[]
go (x:y:z:['-']) = x:y:z:['-']
go (x:y:z:xs) = x:y:z:',':go xs
go xs = xs
Upvotes: 0
Reputation: 31
Check out the Text.Printf
module in base:
https://hackage.haskell.org/package/base-4.9.0.0/docs/Text-Printf.html
Upvotes: -3
Reputation: 2238
I've had this problem myself. My very pragmatic solution (using Text as T) is this:
T.replace (T.singleton '.') (T.singleton ',') $
T.pack $
showFixed False 42.0
Does not work for separators, though. That was fine with me.
For me Locale is not helpful unless there is a way to set it.
Upvotes: 0
Reputation: 5681
(from hier: http://bluebones.net/2007/02/formatting-decimals-in-haskell/)
Formatting Decimals in Haskell
A formatting function to go from numbers like 333999333.33 to “333,999,999.33″ in Haskell. Copes with negative numbers and rounds to 2 dp (easy to add a paramater for that should you wish).
Examples:
*Main> formatDecimal 44
"44.00"
*Main> formatDecimal 94280943.4324
"94,280,943.43"
*Main> formatDecimal (-89438.329)
"-89,438.33"
import Data.Graph.Inductive.Query.Monad (mapFst)
import List
import Text.Printf
formatDecimal d
| d < 0.0 = "-" ++ (formatPositiveDecimal (-d))
| otherwise = formatPositiveDecimal d
where formatPositiveDecimal = uncurry (++) . mapFst addCommas . span (/= '.') . printf "%0.2f"
addCommas = reverse . concat . intersperse "," . unfoldr splitIntoBlocksOfThree . reverse
splitIntoBlocksOfThree l = case splitAt 3 l of ([], _) -> Nothing; p-> Just p
Upvotes: 1
Reputation: 8809
Perhaps you could use some of the functions from Data.Split:
http://hackage.haskell.org/cgi-bin/hackage-scripts/package/split
I know this isn't quite what you want, but you could use Data.List.intersperse
http://haskell.org/ghc/docs/6.12.1/html/libraries/base-4.2.0.0/Data-List.html#v:intersperse
EDIT: This does what you want, although I know you want a library function, this may be as close as you get (please excuse my poor coding style):
import Data.List.Split
import Data.List
format x = h++t
where
sp = break (== '.') $ show x
h = reverse (intercalate "," $ splitEvery 3 $ reverse $ fst sp)
t = snd sp
Upvotes: 10