Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions src/Data/Number.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
exports.fromStringImpl = function (just) {
return function (nothing) {
return function (string) {
var result = parseFloat(string);

return isNaN(result) ? nothing
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe isNaN is not enough here, because parseFloat can also return Infinity (for inputs like 1e1000). isFinite would be a better choice, I think.

Thinking about this, it would be very cool to have isNaN and isFinite available in purescript-numbers. Then, fromString could also be implemented in PureScript.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed on Infinity, will amend now. Interestingly, PureScript's core libraries tend to take the stance that NaN/Infinity is "undefined" behaviour. I wonder what @paf31 would think of isNaN and isFinite existing in PS.

: just(result);
};
};
};
30 changes: 30 additions & 0 deletions src/Data/Number.purs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ module Data.Number
, eqApproximate
, (~=)
, (≅)
, fromString
, neqApproximate
, (≇)
, Precision
Expand All @@ -13,8 +14,37 @@ module Data.Number

import Prelude

import Data.Maybe (Maybe(..))
import Math (abs)


foreign import fromStringImpl
:: (forall a. a -> Maybe a)
-> (forall a. Maybe a)
-> String
-> Maybe Number


-- | Attempt to parse a Number from a String using JavaScript's parseFloat.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should probably specify when to expect a Nothing result here.

-- |
-- | Example:
-- | ```purs
-- | > fromString "123"
-- | (Just 123.0)
-- |
-- | > fromString "12.34"
-- | (Just 12.34)
-- |
-- | > fromString "1e4"
-- | (Just 10000.0)
-- |
-- | > fromString "1.2e4"
-- | (Just 12000.0)
-- | ```
fromString :: String -> Maybe Number
fromString = fromStringImpl Just Nothing


-- | A type alias for (small) numbers, typically in the range *[0:1]*.
type Fraction = Number

Expand Down
22 changes: 21 additions & 1 deletion test/Main.purs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ module Test.Main where

import Prelude

import Data.Number (eqRelative, eqAbsolute, (≅), (≇))
import Data.Maybe (fromMaybe)
import Data.Number (eqRelative, eqAbsolute, fromString, (≅), (≇))

import Control.Monad.Aff.AVar (AVAR)
import Control.Monad.Eff (Eff)
Expand Down Expand Up @@ -119,6 +120,25 @@ main = runTest do
0.1 + 0.200001 ≇ 0.3


suite "fromString" do
test "valid number string" do
assert "integer strings are coerced" $
fromMaybe false $ map (_ == 123.0) $ fromString "123"

assert "decimals are coerced" $
fromMaybe false $ map (_ == 12.34) $ fromString "12.34"

assert "exponents are coerced" $
fromMaybe false $ map (_ == 1e4) $ fromString "1e4"

assert "decimals exponents are coerced" $
fromMaybe false $ map (_ == 1.2e4) $ fromString "1.2e4"

test "invalid number string" do
assert "invalid strings are not coerced" $
fromMaybe true $ false <$ fromString "bad string"

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for adding tests, too! Could you also add a test for an input like 1e1000?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, will do :)


suite "eqAbsolute" do
test "eqAbsolute" do
assert "should succeed for differences smaller than the precision" $
Expand Down