dwayne/elm-natural/1.0.0

NOTE: the latest version is 1.1.1

Natural

Compute with the natural numbers, ℕ = { 0, 1, 2, ... }.

Representation

type Natural

A representation of the natural numbers.

The size of the numbers you can compute with is only limited by the available memory.

The largest integer, currently 2^53 - 1, which can be given as input to fromInt and fromSafeInt without causing problems.

Constants

The natural number 0.

To be more precise, it is a representation of the natural number 0. However, I will not have any cause to make that distinction. A similar remark can be made about the other constants.

The natural number 1.

The natural number 2.

The natural number 3.

The natural number 4.

The natural number 5.

The natural number 6.

The natural number 7.

The natural number 8.

The natural number 9.

The natural number 10.

Constructors

fromInt : Int -> Maybe Natural

Create the natural number represented by the given integer.

fromInt 0 == Just zero


fromInt 1 == Just one


fromInt maxSafeInt == fromString "9007199254740991"

Unless the integer is negative or greater than maxSafeInt.

fromInt -1 == Nothing


fromInt (maxSafeInt + 1) == Nothing

Use this function when you know the integer is non-negative and less than or equal to maxSafeInt.

If the integer isn't in the safe range then zero is returned.

fromSafeInt -1 == zero


fromSafeInt (maxSafeInt + 1) == zero

This function is useful for establising small constants in a calculation. For e.g. to compute the first 100 digits of π the natural number 239 is needed.

twoThirtyNine : Natural
twoThirtyNine =
    fromSafeInt 239
fromBinaryString : String -> Maybe Natural

Create the natural number represented by the given binary string.

binary ::= [0-1]+

For e.g.

fromBinaryString "0" == Just zero


fromBinaryString "1010" == Just ten


fromBinaryString "" == Nothing


fromBinaryString "2" == Nothing
fromOctalString : String -> Maybe Natural

Create the natural number represented by the given octal string.

octal ::= [0-7]+

For e.g.

fromOctalString "0" == Just zero


fromOctalString "12" == Just ten


fromOctalString "" == Nothing


fromOctalString "8" == Nothing
fromHexString : String -> Maybe Natural

Create the natural number represented by the given hexadecimal string.

hex ::= [0-9a-fA-F]+

For e.g.

fromHexString "0" == Just zero


fromHexString "a" == Just ten


fromHexString "A" == Just ten


fromHexString "FE" == fromInt 254


fromHexString "" == Nothing


fromHexString "G" == Nothing
fromString : String -> Maybe Natural

Create the natural number represented by the given string.

input   ::= ('0b' | '0B') binary
          | ('0o' | '0O') octal
          | ('0x' | '0X') hex
          | decimal
binary  ::= [0-1]+
octal   ::= [0-7]+
hex     ::= [0-9a-fA-F]+
decimal ::= [0-9]+

For e.g.

fromString "0b10101101" == fromInt 173


fromString "0o255" == fromInt 173


fromString "0XaD" == fromInt 173


fromString "173" == fromInt 173


fromString "b10101101" == Nothing


fromString "aD" == Nothing


fromString "0x" == Nothing

It's best to use this function when you know the string you're dealing with is a valid input to the fromString function. If the input is invalid then zero is returned.

This function is useful for establishing large constants in a calculation.

oneGoogol : Natural
oneGoogol =
    -- 10 ^ 100
    fromSafeString "10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"

Learn more about a googol.

What's considered a large constant?

Since fromSafeInt n can be used for 0 <= n <= maxSafeInt then it makes sense to consider any number larger than maxSafeInt, a large constant.

fromBaseBString : Int -> String -> Maybe Natural

Create the natural number represented by the given base-b string.

b must be between 2 and 36 inclusive and each character in the string must be a valid base-b digit.

About base-b digits

A valid base-b digit is any digit d such that 0 <= d <= b - 1.

For bases larger than 10, we use case-insensitive letters from the Latin alphabet to represent the base-b digits that are 10 or larger. So,

A or a represents 10
B or b represents 11
C or c represents 12
...
Z or z represents 35

For e.g.

If b = 16 then the valid base-16 digits are [0-9a-fA-F].

If b = 36 then the valid base-36 digits are [0-9a-zA-Z].

fromBaseBString 2 "1010" == Just ten


fromBaseBString 16 "aD" == fromInt 173


fromBaseBString 36 "z" == fromInt 35


fromBaseBString 2 "" == Nothing


fromBaseBString 10 "A" == Nothing

Comparison

To test for equality between two natural numbers you can use == and /=.

add two two == four


mul three three /= six

For all other comparisons you will have to use the functions below.

compare : Natural -> Natural -> Order

Compare any two natural numbers.

compare three four == LT


compare four four == EQ


compare five four == GT

Determine if the second natural number is less than the first.

isLessThan eight two == True


isLessThan two two == False


isLessThan two eight == False

Determine if the second natural number is less than or equal to the first.

isLessThanOrEqual eight two == True


isLessThanOrEqual two two == True


isLessThanOrEqual two eight == False

Determine if the second natural number is greater than the first.

isGreaterThan eight two == False


isGreaterThan two two == False


isGreaterThan two eight == True

Determine if the second natural number is greater than or equal to the first.

isGreaterThanOrEqual eight two == False


isGreaterThanOrEqual two two == True


isGreaterThanOrEqual two eight == True

Find the larger of two natural numbers.

max five ten == ten


max ten five == ten

Find the smaller of two natural numbers.

min five ten == five


min ten five == five

Predicates

isZero : Natural -> Bool

Determine if the natural number is 0.

isZero zero == True


isZero one == False
isOne : Natural -> Bool

Determine if the natural number is 1.

isOne zero == False


isOne one == True

Determine if the natural number is positive.

isPositive zero == False


isPositive one == True
isEven : Natural -> Bool

Determine if the natural number is even.

isEven zero == True


isEven one == False


isEven two == True


isEven three == False
isOdd : Natural -> Bool

Determine if the natural number is odd.

isOdd zero == False


isOdd one == True


isOdd two == False


isOdd three == True

Arithmetic

Add two natural numbers.

Subtract the second natural number from the first.

sub ten four == six

It uses saturating subtraction. Thus, if the second natural number is larger than the first, 0 is returned.

sub four ten == zero

Multiply two natural numbers.

Find the quotient and remainder when the second natural number is divided by the first. This is called Euclidean division or division with remainder.

For e.g.

divModBy two nine == Just ( four, one )

Why? Because,

nine == add (mul four two) one

Division by 0 is not allowed. So, for all n : Natural,

divModBy zero n == Nothing

Note: The performance of this function is subpar and will be improved in a future release.

Find the quotient when the second natural number is divided by the first.

divBy two nine == Just four

Division by 0 is not allowed. So, for all n : Natural,

divModBy zero n == Nothing

Note: The performance of this function is subpar and will be improved in a future release.

Find the remainder when the second natural number is divided by the first.

modBy two nine == Just one

Modulo by 0 is not allowed. So, for all n : Natural,

modBy zero n == Nothing

Note: The performance of this function is subpar and will be improved in a future release.

Find the power of the first natural number (called the base) to the second natural number (called the exponent).

exp two three == eight

For all p : Natural, where p >= 1 (i.e. p is a positive natural number),

exp p zero == one


exp zero p == zero

What is 0^0?

exp zero zero == one

Conversion

toInt : Natural -> Int

Convert any natural number, n, to n mod (maxSafeInt + 1).

toInt zero == 0


toInt ten == 10


toInt (fromSafeInt maxSafeInt) == maxSafeInt


toInt (add (fromSafeInt maxSafeInt) one) == 0


toInt (add (fromSafeInt maxSafeInt) ten) == 9

Convert any natural number to its binary (base-2) representation.

toBinaryString zero == "0"


toBinaryString one == "1"


toBinaryString ten == "1010"


toBinaryString (fromSafeInt 1729) == "11011000001"


toBinaryString (add (fromSafeInt maxSafeInt) one) == "100000000000000000000000000000000000000000000000000000"

Convert any natural number to its octal (base-8) representation.

toOctalString zero == "0"


toOctalString one == "1"


toOctalString ten == "12"


toOctalString (fromSafeInt 1729) == "3301"


toOctalString (add (fromSafeInt maxSafeInt) one) == "400000000000000000"
toHexString : Natural -> String

Convert any natural number to its hexadecimal (base-16) representation.

toHexString zero == "0"


toHexString one == "1"


toHexString ten == "A"


toHexString (fromSafeInt 1729) == "6C1"


toHexString (add (fromSafeInt maxSafeInt) one) == "20000000000000"
toString : Natural -> String

Convert any natural number to its decimal (base-10) representation.

toString zero == "0"


toString one == "1"


toString ten == "10"


toString (fromSafeInt 1729) == "1729"


toString (add (fromSafeInt maxSafeInt) one) == "9007199254740992"
toBaseBString : Int -> Natural -> Maybe String

Convert any natural number to its base-b representation.

b must be between 2 and 36 inclusive and each character in the resulting string will be a valid base-b digit.

All Latin letters in the base-b representation will be in uppercase.

For e.g.

toBaseBString 2 (fromSafeInt 1729) == Just "11011000001"


toBaseBString 8 (fromSafeInt 1729) == Just "3301"


toBaseBString 10 (fromSafeInt 1729) == Just "1729"


toBaseBString 16 (fromSafeInt 1729) == Just "6C1"


toBaseBString 36 (fromSafeInt 1729) == Just "1C1"

For any k : Int where k < 2 or k > 36, and any n : Natural,

toBaseBString k n == Nothing

N.B. Please refer to fromBaseBString to learn more about base-b digits.