Skip to content

Fix signum implementation #280

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 12 commits into from
Mar 16, 2022
Merged
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ Breaking changes:
- Migrated FFI to ES Modules (#287 by @kl0tl and @JordanMartinez)
- Change Generic Rep's `NoConstructors` to newtype `Void` (#282 by @JordanMartinez)
- Replaced polymorphic proxies with monomorphic `Proxy` (#281, #288 by @JordanMartinez)
- Fix `signum zero` to return `zero` (#280 by @JordanMartinez)

New features:

Expand Down
12 changes: 9 additions & 3 deletions src/Data/Ord.purs
Original file line number Diff line number Diff line change
Expand Up @@ -216,10 +216,16 @@ between low hi x
abs :: forall a. Ord a => Ring a => a -> a
abs x = if x >= zero then x else negate x

-- | The sign function; always evaluates to either `one` or `negate one`. For
-- | any `x`, we should have `signum x * abs x == x`.
-- | The sign function; returns `one` if the argument is positive,
-- | `negate one` if the argument is negative, or `zero` if the argument is `zero`.
-- | For floating point numbers with signed zeroes, when called with a zero,
-- | this function returns the argument in order to preserve the sign.
-- | For any `x`, we should have `signum x * abs x == x`.
signum :: forall a. Ord a => Ring a => a -> a
signum x = if x >= zero then one else negate one
signum x =
if x < zero then negate one
else if x > zero then one
else x

-- | The `Ord1` type class represents totally ordered type constructors.
class Eq1 f <= Ord1 f where
Expand Down
10 changes: 9 additions & 1 deletion test/Test/Main.purs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ module Test.Main where

import Prelude
import Data.HeytingAlgebra (ff, tt, implies)
import Data.Ord (abs)
import Data.Ord (abs, signum)
import Test.Data.Generic.Rep (testGenericRep)
import Test.Utils (AlmostEff, assert)

Expand All @@ -15,6 +15,7 @@ main = do
testIntDegree
testRecordInstances
testGenericRep
testSignum

foreign import testNumberShow :: (Number -> String) -> AlmostEff

Expand Down Expand Up @@ -151,3 +152,10 @@ testRecordInstances = do
assert "Record top" $
(top :: { a :: Boolean }).a
== top

testSignum :: AlmostEff
testSignum = do
assert "Clarifies what 'signum positive zero' test is doing" $ show (1.0/0.0) == "Infinity"
assert "signum positive zero" $ show (1.0/(signum 0.0)) == "Infinity"
assert "Clarifies what 'signum negative zero' test is doing" $ show (1.0/(-0.0)) == "-Infinity"
assert "signum negative zero" $ show (1.0/(signum (-0.0))) == "-Infinity"