Skip to content

Commit

Permalink
Fill out API for BigInt
Browse files Browse the repository at this point in the history
  • Loading branch information
kozross committed Oct 11, 2023
1 parent e2565cb commit e2a7b35
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 2 deletions.
8 changes: 8 additions & 0 deletions src/Contract/Numeric/BigInt.purs
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,18 @@ module Contract.Numeric.BigInt (module X) where
import Ctl.Internal.Types.BigInt
( BigInt
, abs
, even
, fromBase
, fromInt
, fromNumber
, fromString
, fromTLInt
, odd
, pow
, toBase
, toBase'
, toInt
, toNonEmptyString
, toNumber
, toString
) as X
62 changes: 60 additions & 2 deletions src/Internal/Types/BigInt.purs
Original file line number Diff line number Diff line change
@@ -1,13 +1,21 @@
-- | Arbitrary-precision integers (backed by 'purescript-js-bigint').
module Ctl.Internal.Types.BigInt
( BigInt(UnsafeBigInt)
( BigInt
, toString
, toNonEmptyString
, fromString
, fromBase
, toBase
, toBase'
, toInt
, fromInt
, fromTLInt
, toNumber
, fromNumber
, abs
, even
, odd
, pow
) where

import Prelude
Expand All @@ -20,9 +28,15 @@ import Aeson
, encodeAeson
)
import Data.Either (Either(Left))
import Data.Int (decimal, radix)
import Data.Maybe (Maybe(Nothing, Just))
import Data.Maybe (fromMaybe)
import Data.Reflectable (class Reflectable)
import Data.String.NonEmpty.Internal (NonEmptyString(NonEmptyString))
import JS.BigInt as BigIntImpl
import Prim (Int, Number, String)
import Prim (Boolean, Int, Number, String, Symbol)
import Prim.Int (class ToString)
import Type.Proxy (Proxy)

newtype BigInt = UnsafeBigInt BigIntImpl.BigInt

Expand Down Expand Up @@ -70,6 +84,40 @@ toString (UnsafeBigInt bi) = BigIntImpl.toString bi
fromString :: String -> Maybe BigInt
fromString = BigIntImpl.fromString >>> map UnsafeBigInt

-- | String will be a decimal representation
toNonEmptyString :: BigInt -> NonEmptyString
toNonEmptyString = toString >>> NonEmptyString

-- | Parse a string into a `BigInt`, assuming a representation in the given
-- | base. The letters "a-z" and "A-Z" will be interpreted as the digits `10`
-- | to `36`.
-- |
-- | Returns Nothing if either the parse fails, or the given `Int` is not a
-- | valid base.
fromBase :: Int -> String -> Maybe BigInt
fromBase base src = radix base >>= \r ->
UnsafeBigInt <$> BigIntImpl.fromStringAs r src

-- | As `toString`, but in the base given by the `Int` argument.
-- |
-- | Note: for compatibility with the `Data.BigInt` API, this defaults to
-- | base-10 if given a base argument that doesn't make sense.
toBase :: Int -> BigInt -> String
toBase base (UnsafeBigInt bi) =
BigIntImpl.toStringAs (fromMaybe decimal $ radix base) bi

-- | As `toBase`, but produces a `NonEmptyString`.
toBase' :: Int -> BigInt -> NonEmptyString
toBase' base = toBase base >>> NonEmptyString

fromTLInt
:: forall (i :: Int) (sym :: Symbol)
. Reflectable sym String
=> ToString i sym
=> Proxy i
-> BigInt
fromTLInt p = UnsafeBigInt $ BigIntImpl.fromTLInt p

toInt :: BigInt -> Maybe Int
toInt (UnsafeBigInt bi) = BigIntImpl.toInt bi

Expand All @@ -90,3 +138,13 @@ abs :: BigInt -> BigInt
abs bi = case compare bi (fromInt 0) of
LT -> negate bi
_ -> bi

even :: BigInt -> Boolean
even (UnsafeBigInt bi) = BigIntImpl.even bi

odd :: BigInt -> Boolean
odd (UnsafeBigInt bi) = BigIntImpl.odd bi

pow :: BigInt -> BigInt -> BigInt
pow (UnsafeBigInt b) (UnsafeBigInt e) =
UnsafeBigInt $ BigIntImpl.pow b e

0 comments on commit e2a7b35

Please sign in to comment.