Skip to content

Commit 21cf05d

Browse files
committed
Add functions for formatting numbers, closes #6
1 parent 755b960 commit 21cf05d

File tree

4 files changed

+142
-7
lines changed

4 files changed

+142
-7
lines changed

README.md

+20-6
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
[![Latest release](http://img.shields.io/github/release/sharkdp/purescript-numbers.svg)](https://github.com/sharkdp/purescript-numbers/releases)
33
[![Build status](https://travis-ci.org/sharkdp/purescript-numbers.svg?branch=master)](https://travis-ci.org/sharkdp/purescript-numbers)
44

5-
Functions for working with PureScripts builtin `Number` type.
5+
Utility functions for working with PureScripts builtin `Number` type.
66

77
* [**Module documentation on Pursuit**](http://pursuit.purescript.org/packages/purescript-numbers).
88

@@ -17,13 +17,18 @@ Parsing:
1717
(Just 0.001)
1818
```
1919

20-
*NaN* and *infinity*:
20+
Formatting (`Data.Number.Format`):
2121
``` purs
22-
> isNaN (Math.asin 2.0)
23-
true
22+
> let x = 1234.56789
2423
25-
> isFinite (1.0 / 0.0)
26-
false
24+
> toStringWith (precision 6) x
25+
"1234.57"
26+
27+
> toStringWith (fixed 3) x
28+
"1234.568"
29+
30+
> toStringWith (exponential 2) x
31+
"1.23e+3"
2732
```
2833

2934
Approximate comparisons (`Data.Number.Approximate`):
@@ -35,6 +40,15 @@ false
3540
true
3641
```
3742

43+
*NaN* and *infinity*:
44+
``` purs
45+
> isNaN (Math.asin 2.0)
46+
true
47+
48+
> isFinite (1.0 / 0.0)
49+
false
50+
```
51+
3852
## Installation
3953

4054
```

src/Data/Number/Format.js

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
function wrap(method) {
2+
return function(d) {
3+
return function(num) {
4+
return method.apply(num, [d]);
5+
};
6+
};
7+
}
8+
9+
exports.toPrecisionNative = wrap(Number.prototype.toPrecision);
10+
exports.toFixedNative = wrap(Number.prototype.toFixed);
11+
exports.toExponentialNative = wrap(Number.prototype.toExponential);
12+
13+
exports.toString = function(num) { return num.toString(); };

src/Data/Number/Format.purs

+76
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
-- | A module for formatting numbers as strings.
2+
-- |
3+
-- | Usage:
4+
-- | ``` purs
5+
-- | > let x = 1234.56789
6+
-- |
7+
-- | > toStringWith (precision 6) x
8+
-- | "1234.57"
9+
-- |
10+
-- | > toStringWith (fixed 3) x
11+
-- | "1234.568"
12+
-- |
13+
-- | > toStringWith (exponential 2) x
14+
-- | "1.23e+3"
15+
-- | ```
16+
-- |
17+
-- | The main method of this module is the `toStringWith` function that accepts
18+
-- | a `Format` argument which can be constructed through one of the smart
19+
-- | constructors `precision`, `fixed` and `exponential`. Internally, the
20+
-- | number will be formatted with JavaScripts `toPrecision`, `toFixed` or
21+
-- | `toExponential`.
22+
module Data.Number.Format
23+
( Format()
24+
, precision
25+
, fixed
26+
, exponential
27+
, toStringWith
28+
, toString
29+
) where
30+
31+
import Prelude
32+
33+
foreign import toPrecisionNative Int Number String
34+
foreign import toFixedNative Int Number String
35+
foreign import toExponentialNative Int Number String
36+
37+
-- | The `Format` data type specifies how a number will be formatted.
38+
data Format
39+
= Precision Int
40+
| Fixed Int
41+
| Exponential Int
42+
43+
-- | Create a `toPrecision`-based format from an integer. Values smaller than
44+
-- | `1` and larger than `21` will be clamped.
45+
precision Int Format
46+
precision = Precision <<< clamp 1 21
47+
48+
-- | Create a `toFixed`-based format from an integer. Values smaller than `0`
49+
-- | and larger than `20` will be clamped.
50+
fixed Int Format
51+
fixed = Fixed <<< clamp 0 20
52+
53+
-- | Create a `toExponential`-based format from an integer. Values smaller than
54+
-- | `0` and larger than `20` will be clamped.
55+
exponential Int Format
56+
exponential = Exponential <<< clamp 0 20
57+
58+
-- | Convert a number to a string with a given format.
59+
toStringWith Format Number String
60+
toStringWith (Precision p) = toPrecisionNative p
61+
toStringWith (Fixed p) = toFixedNative p
62+
toStringWith (Exponential p) = toExponentialNative p
63+
64+
-- | Convert a number to a string via JavaScript's toString method.
65+
-- |
66+
-- | ```purs
67+
-- | > toString 12.34
68+
-- | "12.34"
69+
-- |
70+
-- | > toString 1234.0
71+
-- | "1234"
72+
-- |
73+
-- | > toString 1.2e-10
74+
-- | "1.2e-10"
75+
-- | ```
76+
foreign import toString Number String

test/Main.purs

+33-1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ import Prelude
44

55
import Data.Maybe (Maybe(..), fromMaybe)
66
import Data.Number (nan, isNaN, infinity, isFinite, fromString)
7+
import Data.Number.Format (precision, fixed, exponential, toStringWith,
8+
toString)
79
import Data.Number.Approximate (Fraction(..), Tolerance(..), eqRelative,
810
eqAbsolute, (≅), (≇))
911

@@ -12,7 +14,7 @@ import Control.Monad.Eff (Eff)
1214
import Control.Monad.Eff.Console (CONSOLE)
1315

1416
import Test.Unit (suite, test)
15-
import Test.Unit.Assert (assert, assertFalse)
17+
import Test.Unit.Assert (assert, assertFalse, equal)
1618
import Test.Unit.Console (TESTOUTPUT)
1719
import Test.Unit.Main (runTest)
1820

@@ -71,6 +73,36 @@ main = runTest do
7173
assertFalse "detect NaN" $ isFinite nan
7274

7375

76+
let pi = 3.14159
77+
suite "Data.Format.toStringWith" do
78+
79+
test "precision" do
80+
equal "3.14" (toStringWith (precision 3) pi)
81+
equal "3.1416" (toStringWith (precision 5) pi)
82+
equal "3" (toStringWith (precision 1) pi)
83+
equal "3" (toStringWith (precision (-3)) pi)
84+
equal "3.14" (toStringWith (precision 3) pi)
85+
equal "1.2e+3" (toStringWith (precision 2) 1234.5)
86+
87+
test "fixed" do
88+
equal "3.14" (toStringWith (fixed 2) pi)
89+
equal "3.1416" (toStringWith (fixed 4) pi)
90+
equal "3" (toStringWith (precision 0) pi)
91+
equal "3" (toStringWith (precision (-3)) pi)
92+
equal "1234.5" (toStringWith (fixed 1) 1234.5)
93+
94+
test "exponential" do
95+
equal "3e+0" (toStringWith (exponential 0) pi)
96+
equal "3.14e+0" (toStringWith (exponential 2) pi)
97+
equal "3.14e+2" (toStringWith (exponential 2) (100.0 * pi))
98+
equal "1.2e+3" (toStringWith (exponential 1) 1234.5)
99+
100+
suite "Data.Format.toString" do
101+
102+
test "toString" do
103+
equal "3.14159" (toString pi)
104+
equal "10" (toString 10.0)
105+
74106
suite "Data.Number.Approximate.eqRelative" do
75107
test "eqRelative" do
76108
assert "should return true for differences smaller 10%" $

0 commit comments

Comments
 (0)