Skip to content

Commit

Permalink
Use BigInt instead of Int (#42)
Browse files Browse the repository at this point in the history
  • Loading branch information
gbagan committed May 6, 2023
1 parent b480bc4 commit d85ddb5
Show file tree
Hide file tree
Showing 8 changed files with 58 additions and 46 deletions.
8 changes: 2 additions & 6 deletions README.md
Expand Up @@ -40,12 +40,8 @@ bower install purescript-rationals

## Other Ratios

`Rational` is just a type alias for `Ratio Int` and you might want to use
`Ratio` with other than `Int`. The type you choose must however be an `EuclideanRing`.

For example, one limitation with `Rational` is that it can easily overflow
the 32-bit PureScript `Int`. You can get around this problem by using
[`BigInt`](https://pursuit.purescript.org/packages/purescript-bigints/3.1.0/docs/Data.BigInt#t:BigInt).
`Rational` is just a newtype over `Ratio BigInt` and you might want to use
`Ratio` with other than `BigInt`. The type you choose must however be an `EuclideanRing`.

```
> import Data.Ratio ((%), reduce)
Expand Down
20 changes: 0 additions & 20 deletions bower.json

This file was deleted.

11 changes: 3 additions & 8 deletions package.json
@@ -1,18 +1,13 @@
{
"private": true,
"scripts": {
"postinstall": "bower install",
"build": "pulp build",
"test": "pulp test",
"build": "spago build",
"spago-build": "spago build",
"test": "spago -x ./test.dhall test",
"spago-test": "spago -x ./test.dhall test"
},
"devDependencies": {
"big-integer": "^1.6.51",
"bower": "^1.8.14",
"pulp": "^16.0.1",
"purescript": "^0.15.2",
"purs-tidy": "^0.9.2",
"purescript": "^0.15.8",
"spago": "^0.20.9"
}
}
4 changes: 2 additions & 2 deletions packages.dhall
@@ -1,5 +1,5 @@
let upstream =
https://github.com/purescript/package-sets/releases/download/psc-0.15.2-20220706/packages.dhall
sha256:7a24ebdbacb2bfa27b2fc6ce3da96f048093d64e54369965a2a7b5d9892b6031
https://github.com/purescript/package-sets/releases/download/psc-0.15.8-20230503/packages.dhall
sha256:b0ca02f2efb206465b499ee847f174212be0c8c2e031044b7bd192d5294f22cb

in upstream
2 changes: 1 addition & 1 deletion spago.dhall
@@ -1,5 +1,5 @@
{ name = "rationals"
, dependencies = [ "integers", "prelude" ]
, dependencies = [ "integers", "js-bigints", "prelude" ]
, license = "MIT"
, repository = "https://github.com/purescript-contrib/purescript-rationals.git"
, packages = ./packages.dhall
Expand Down
49 changes: 45 additions & 4 deletions src/Data/Rational.purs
@@ -1,19 +1,60 @@
module Data.Rational
( Rational
, (%)
, toNumber
, fromInt
, module Data.Ratio
, fromBigInt
, numerator
, denominator
, class ToRational
, toRational
) where

import Prelude

import Data.Int as Int
import Data.Ratio (Ratio, denominator, numerator, (%))
import Data.Ratio as Ratio
import JS.BigInt (BigInt)
import JS.BigInt as BigInt

type Rational = Ratio Int
newtype Rational = Rational (Ratio.Ratio BigInt)

derive newtype instance Eq Rational
derive newtype instance Ord Rational
derive newtype instance Show Rational
derive newtype instance Semiring Rational
derive newtype instance Ring Rational
derive newtype instance CommutativeRing Rational
derive newtype instance EuclideanRing Rational
derive newtype instance DivisionRing Rational

toNumber :: Rational -> Number
toNumber x = Int.toNumber (numerator x) / Int.toNumber (denominator x)
toNumber (Rational x) = BigInt.toNumber (Ratio.numerator x) / BigInt.toNumber (Ratio.denominator x)

fromInt :: Int -> Rational
fromInt i = i % 1
fromInt i = Rational $ Ratio.reduce (BigInt.fromInt i) (BigInt.fromInt 1)

fromBigInt :: BigInt -> Rational
fromBigInt i = Rational $ Ratio.reduce i (BigInt.fromInt 1)

numerator :: Rational -> BigInt
numerator (Rational x) = Ratio.numerator x

denominator :: Rational -> BigInt
denominator (Rational x) = Ratio.denominator x

class
ToRational a
where
toRational :: a -> a -> Rational

instance ToRational Int
where
toRational a b = Rational $ Ratio.reduce (BigInt.fromInt a) (BigInt.fromInt b)

instance ToRational BigInt
where
toRational a b = Rational $ Ratio.reduce a b

infixl 7 toRational as %
2 changes: 1 addition & 1 deletion test.dhall
Expand Up @@ -2,6 +2,6 @@ let conf = ./spago.dhall

in conf // {
sources = conf.sources # [ "test/**/*.purs" ],
dependencies = conf.dependencies # [ "bigints", "console", "effect", "test-unit", "quickcheck", "quickcheck-laws" ]
dependencies = conf.dependencies # [ "console", "effect", "integers", "quickcheck", "quickcheck-laws" ]
}

8 changes: 4 additions & 4 deletions test/Main.purs
Expand Up @@ -2,10 +2,10 @@ module Test.Main where

import Prelude

import Data.BigInt (BigInt, fromInt)
import Data.Ratio (Ratio, (%))
import Data.Rational (Rational, (%))
import Effect (Effect)
import Effect.Console (log)
import JS.BigInt (BigInt, fromInt)
import Test.QuickCheck (Result, quickCheck', (===))
import Test.QuickCheck.Arbitrary (class Arbitrary, arbitrary)
import Test.QuickCheck.Gen (Gen, suchThat)
Expand All @@ -14,7 +14,7 @@ import Test.QuickCheck.Laws.Data as Data
import Test.QuickCheck.Laws.Data.Field (checkField) as DataField
import Type.Proxy (Proxy(..))

newtype TestRational = TestRational (Ratio BigInt)
newtype TestRational = TestRational Rational

derive newtype instance commutativeRingTestRational :: CommutativeRing TestRational
derive newtype instance eqTestRational :: Eq TestRational
Expand All @@ -41,7 +41,7 @@ instance arbitraryTestRational :: Arbitrary TestRational where
testRational :: Proxy TestRational
testRational = Proxy

newtype TestRatNonZero = TestRatNonZero (Ratio BigInt)
newtype TestRatNonZero = TestRatNonZero Rational

derive newtype instance eqTestRatNonZero :: Eq TestRatNonZero
derive newtype instance semiringTestRatNonZero :: Semiring TestRatNonZero
Expand Down

0 comments on commit d85ddb5

Please sign in to comment.