Skip to content

Commit a3a1041

Browse files
committed
Merge pull request #14 from hdgarrood/conversions-from-number
Add more conversions from `Number`
2 parents f4ef097 + 8987945 commit a3a1041

File tree

4 files changed

+82
-1
lines changed

4 files changed

+82
-1
lines changed

bower.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@
2121
"package.json"
2222
],
2323
"dependencies": {
24-
"purescript-maybe": "^0.3.0"
24+
"purescript-maybe": "^0.3.0",
25+
"purescript-math": "^0.2.0"
2526
},
2627
"devDependencies": {
2728
"purescript-assert": "^0.1.0",

docs/Data/Int.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,33 @@ Creates an `Int` from a `Number` value. The number must already be an
1010
integer and fall within the valid range of values for the `Int` type
1111
otherwise `Nothing` is returned.
1212

13+
#### `floor`
14+
15+
``` purescript
16+
floor :: Number -> Int
17+
```
18+
19+
Convert a `Number` to an `Int`, by taking the closest integer equal to or
20+
less than the argument. Values outside the `Int` range are clamped.
21+
22+
#### `ceil`
23+
24+
``` purescript
25+
ceil :: Number -> Int
26+
```
27+
28+
Convert a `Number` to an `Int`, by taking the closest integer equal to or
29+
greater than the argument. Values outside the `Int` range are clamped.
30+
31+
#### `round`
32+
33+
``` purescript
34+
round :: Number -> Int
35+
```
36+
37+
Convert a `Number` to an `Int`, by taking the nearest integer to the
38+
argument. Values outside the `Int` range are clamped.
39+
1340
#### `toNumber`
1441

1542
``` purescript

src/Data/Int.purs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
module Data.Int
22
( fromNumber
3+
, ceil
4+
, floor
5+
, round
36
, toNumber
47
, fromString
58
, even
@@ -10,6 +13,8 @@ import Prelude
1013

1114
import Data.Int.Bits
1215
import Data.Maybe (Maybe(..))
16+
import qualified Data.Maybe.Unsafe as U
17+
import qualified Math as Math
1318

1419
-- | Creates an `Int` from a `Number` value. The number must already be an
1520
-- | integer and fall within the valid range of values for the `Int` type
@@ -22,6 +27,30 @@ foreign import fromNumberImpl :: (forall a. a -> Maybe a)
2227
-> Number
2328
-> Maybe Int
2429

30+
-- | Convert a `Number` to an `Int`, by taking the closest integer equal to or
31+
-- | less than the argument. Values outside the `Int` range are clamped.
32+
floor :: Number -> Int
33+
floor = unsafeClamp <<< Math.floor
34+
35+
-- | Convert a `Number` to an `Int`, by taking the closest integer equal to or
36+
-- | greater than the argument. Values outside the `Int` range are clamped.
37+
ceil :: Number -> Int
38+
ceil = unsafeClamp <<< Math.ceil
39+
40+
-- | Convert a `Number` to an `Int`, by taking the nearest integer to the
41+
-- | argument. Values outside the `Int` range are clamped.
42+
round :: Number -> Int
43+
round = unsafeClamp <<< Math.round
44+
45+
-- | Convert an integral `Number` to an `Int`, by clamping to the `Int` range.
46+
-- | This function will throw an error at runtime if the argument is
47+
-- | non-integral.
48+
unsafeClamp :: Number -> Int
49+
unsafeClamp x
50+
| x >= toNumber (top :: Int) = top
51+
| x <= toNumber (bottom :: Int) = bottom
52+
| otherwise = U.fromJust $ fromNumber x
53+
2554
-- | Converts an `Int` value back into a `Number`. Any `Int` is a valid `Number`
2655
-- | so there is no loss of precision with this function.
2756
foreign import toNumber :: Int -> Number

test/Test/Data/Int.purs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,30 @@ testInt = do
2323
assert $ toNumber (-1) == -1.0
2424
assert $ toNumber 0 == 0.0
2525

26+
log "round should choose the closest integer"
27+
assert $ round 0.3 == 0
28+
assert $ round 0.7 == 1
29+
30+
log "ceil should round up"
31+
assert $ ceil 0.3 == 1
32+
assert $ ceil 0.7 == 1
33+
34+
log "floor should round down"
35+
assert $ floor 0.3 == 0
36+
assert $ floor 0.7 == 0
37+
38+
log "round, ceil, and floor should clamp values outside the Int range"
39+
let testClamping f = do
40+
let low = toNumber bottom - 1.5
41+
assert $ f low == bottom
42+
43+
let high = toNumber top + 1.5
44+
assert $ f high == top
45+
46+
testClamping round
47+
testClamping ceil
48+
testClamping floor
49+
2650
log "fromString should read integers"
2751
assert $ fromString "0" == Just 0
2852
assert $ fromString "9467" == Just 9467

0 commit comments

Comments
 (0)