indique/elm-bounded-nat/11.0.0

NOTE: the latest version is 13.0.0

MinNat

2 situations where you use these operations instead of the ones in InNat:

  1. Your value is of type Nat (ValueMin ...)

    nat3 |> MinNat.mul nat3
    --> Nat (ValueMin Nat3)
  2. The maximum isn't fixed

    divideBy : Nat (In (Nat1Plus minMinus1) max maybeN) -> --...

compare

is :
Nat
(In (Nat1Plus triedMinus1) (Nat1Plus triedMinus1PlusA) maybeN)
-> { min : Nat (N min (Is minToTriedMinus1 To) triedMinus1 x) }
-> { equal : () -> result
, less : Nat (ValueIn min triedMinus1PlusA) -> result
, greater : Nat (ValueMin (Nat2Plus triedMinus1)) -> result
}
-> Nat (In min max maybeN)
-> result

Compare the Nat (ValueMin ...) to a Nat (N ...). Is it greater, less or equal?

min ensures that the Nat (N ...) is bigger than the minimum.

present =
    MinNat.lowerMin nat0
        >> MinNat.is nat18
            { min = nat0 }
            { less = \age -> appropriateToy { age = age }
            , greater = \age -> appropriateExperience { age = age }
            , equal = \() -> bigPresent
            }


appropriateToy : { age : Nat (In Nat0 Nat17 maybeN) } -> Toy


appropriateExperience : { age : Nat (In Nat19 max maybeN) } -> Experience
Nat (In triedMin (Nat1Plus triedMinMinus1PlusA) maybeN)
-> { min : Nat (N min (Is minToTriedMin To) triedMin x) }
-> { less : Nat (ValueIn min triedMinMinus1PlusA) -> result
, equalOrGreater : Nat (ValueMin triedMin) -> result
}
-> Nat (In min max maybeN)
-> result

Is the Nat (ValueMin ...)

  • equalOrGreater than a Nat or

  • less?

factorial : MinNat min -> MinNat Nat1
factorial =
    MinNat.lowerMin nat0
        >> MinNat.isAtLeast nat1
            { min = nat0 }
            { less = \_ -> nat1 |> InNat.toMin
            , equalOrGreater =
                \atLeast1 ->
                    atLeast1
                        |> MinNat.mul
                            (factorial
                                (atLeast1 |> MinNat.subN nat1)
                            )
            }
Nat (In atMostMin atMostMinPlusA atMostMaybeN)
-> { min : Nat (N min (Is minToAtMostMin To) atMostMin x) }
-> { equalOrLess : Nat (ValueIn min atMostMinPlusA) -> result
, greater : Nat (ValueMin atMostMin) -> result
}
-> Nat (In min max maybeN)
-> result

Is the Nat (ValueMin ...)

  • equalOrLess than a Nat or

  • greater?

goToU18Party : { age : Nat (In min Nat17 maybeN) } -> List Snack

tryToGoToU18Party =
    MinNat.lowerMin nat0
        >> MinNat.isAtMost nat17
            { min = nat0 }
            { equalOrLess = \age -> Just (goToU18Party { age = age })
            , greater = Nothing
            }

modify

Nat (N sub (Is differenceMin To) min x)
-> Nat (In min max maybeN)
-> Nat (ValueIn differenceMin max)

Subtract an exact Nat (N ...).

(nat7 |> NNat.toMin)
    |> MinNat.subN nat2
--> is of type Nat (ValueMin Nat5)
add :
Nat (In addedMin addedMax maybeN)
-> Nat (N addedMin (Is min To) sumMin x)
-> Nat (In min max maybeN)
-> Nat (ValueMin sumMin)

Add a Nat (ValueMin ...). The second argument is the minimum if the added Nat (ValueMin ...).

nat5
    |> NNat.toMin
    |> MinNat.add atLeast2 nat2
--> is of type Nat (ValueMin Nat7)

If you have don't the minimum added value at hand, use InNat.addLossy.

sub :
Nat (In minSubbed maxSubbed subbedMaybeN)
-> Nat (N maxSubbed (Is differenceMin To) min x)
-> Nat (In min max maybeN)
-> Nat (ValueIn differenceMin max)

Subtract a Nat (In ...). The second argument is the maximum of the subtracted Nat (In ...).

atLeast6 |> MinNat.sub in0To5 nat5
--> is of type Nat (In Nat1 (Nat6Plus a))

If you have don't the maximum subtracted value at hand, use subLossy.

Nat (N added (Is min To) sumMin x)
-> Nat (In min max maybeN)
-> Nat (ValueMin sumMin)

Add a fixed Nat (N ...) value.

nat70
    |> NNat.toMin
    |> InNat.addN nat7

Every other available operation:

drop information

Nat (In lowerMin min lowerMaybeN)
-> Nat (In min max maybeN)
-> Nat (ValueIn lowerMin max)

Set the minimum lower.

[ atLeast3, atLeast4 ]

Elm complains:

But all the previous elements in the list are: Nat (ValueMin Nat3)

[ atLeast3
, atLeast4 |> MinNat.lowerMin nat3
]

modify

Nat (In (Nat1Plus powMinMinus1) powMax powMaybeN)
-> Nat (In min max maybeN)
-> Nat (ValueMin min)

The Nat (ValueMin ...) ^ a Nat (ValueMin ...). We know that if a >= 1 → x ^ a >= x

atLeast5 |> MinNat.toPower nat2
--> Nat 25 of type Nat (ValueMin Nat5)


atLeast2 |> MinNat.toPower nat5
--> Nat 25 of type Nat (ValueMin Nat2)
Nat (In (Nat1Plus divMinMinus1) divMax divMaybeN)
-> Nat (In min max maybeN)
-> Nat (ValueIn Nat0 max)

The remainder after division.

  • % 0 is impossible
  • x % d is at most x
atMost7 |> InNat.remainderBy nat3
--> Nat 1 of type Nat (In Nat0 (Nat7Plus a))
mul :
Nat
(In
(Nat1Plus minMultipliedMinus1)
maxMultiplied
multipliedMaybeN
)
-> Nat (In min max maybeN)
-> Nat (ValueMin min)

Multiply by a Nat (In ...) >= 1. we know that if a >= 1, x * a >= x.

atLeast5  |> MinNat.mul nat2
--> Nat 10 of type Nat (ValueMin Nat5)


atLeast2 |> MinNat.mul nat5
--> Nat 10 of type Nat (ValueMin Nat2)

The maximum value of both factors can be Infinity.

div :
Nat (In (Nat1Plus divMinMinus1) divMax divMaybeN)
-> Nat (In min max maybeN)
-> Nat (ValueIn Nat0 max)

Divide (//) by a Nat (In ...).

  • / 0 is impossible

  • x / d is at most x

atMost7
    |> InNat.div nat3
--> Nat 2 of type Nat (ValueIn Nat0 (Nat7Plus a))

compare

Nat (In newMin max lowerMaybeN)
-> Nat (In min max maybeN)
-> Nat (ValueIn newMin max)

If the Nat (In ...) is less than a number, return that number instead.

nat5 |> NNat.toIn
    |> InNat.atLeast nat10
--> Nat 10


nat15 |> NNat.toIn
    |> InNat.atLeast nat10
--> Nat 15