A natural number within a minimum & maximum.
If the Nat (In ...) is less than a number, return that number instead.
nat5 |> Nat.N.toIn
|> Nat.In.atLeast nat10
--> Nat 10
nat15 |> Nat.N.toIn
|> Nat.In.atLeast (nat10 |> Nat.N.toIn)
--> Nat 15Cap the Nat (In ...) to at most a number.
nat5 |> Nat.N.toIn
|> Nat.In.atMost nat10 { min = nat5 }
--> Nat.In 5
nat15 |> Nat.N.toIn
|> Nat.In.lowerMin nat5
|> Nat.In.atMost nat10 { min = nat5 }
--> Nat 10min ensures that that number is at least the minimum.
Compare the Nat (In ...) to a Nat (N ...). Is it greater, less or equal?
min ensures that the Nat (N ...) is bigger than the minimum.
is4 =
Nat.In.lowerMin (nat0 |> Nat.N.toIn)
>> is ( nat4, nat4 ) { min = nat0 }
{ greater = \x-> Err (Nat.toInt x ++ " is greater than 4")
, less = \x-> Err (Nat.toInt x ++ " is less than 4")
, equal = \() -> Ok ()
}
is4 (Nat.N.toIn nat4)
--> OK ()
is4 (Nat.N.toIn nat3)
--> Err "3 is less than 4"Compared to a range first to last, is the Nat (In ...)
inRange
greater than the last or
less than the first?
justIfBetween3And10 =
Nat.In.lowerMin nat0
>> Nat.In.isInRange
{ first = ( nat3, nat3 ), last = ( nat10, nat10 ) }
{ min = nat0 }
{ less = \_ -> Nothing
, greater = \_ -> Nothing
, inRange = Just
}
justIfBetween3And10 (nat9 |> Nat.N.toIn)
--> Just (Nat 9)
justIfBetween3And10 (nat123 |> Nat.N.toIn)
--> NothingAn Int compared to a range from first to last.
rejectOrAcceptUserInt =
isIntInRange { first = nat1, last = nat100 }
{ less = Err "must be >= 1"
, more = Err "must be <= 100"
, inRange = Ok
}
rejectOrAcceptUserInt (Nat.N.toIn nat0)
--> Err "must be >= 1"Is the Nat (In ...)
equalOrGreater than a Nat or
less?
vote : { age : Nat (In (Nat18Plus orOlder) max) } -> Vote
tryToVote =
Nat.In.lowerMin nat0
>> Nat.In.isAtLeast ( nat18, nat18 )
{ min = nat0 }
{ less = Nothing --😓
, equalOrGreater = \age -> Just (vote { age = age })
}Is the Nat (In ...)
equalOrLess than a Nat or
greater?
goToU18Party : { age : Nat (In min Nat17) } -> List Snack
tryToGoToU18Party =
Nat.In.lowerMin (nat0 |> Nat.N.toIn)
>> Nat.In.isAtMost ( nat17, nat17 )
{ min = nat0 }
{ equalOrLess = \age -> Just (goToU18Party { age 0 age })
, greater = Nothing
}Add a fixed Nat (N ...) value.
Nat.N.toIn nat70
|> Nat.In.addN ( nat7, nat7 )
--> is of type Nat (In Nat77 (Nat77Plus a))Subtract a fixed Nat value.
nat7 |> Nat.N.toIn
|> Nat.In.subN ( nat7, nat7 )
--> is of type Nat (In Nat0 a)Add a Nat (In ...).
Nat.N.toIn nat3
|> Nat.In.add between1And12 nat1 nat12
--> of type Nat (In Nat4 (Nat15Plus a))Subtract a Nat (In ...).
nat6 |> Nat.N.toIn
|> Nat.In.sub between1And5 nat1 nat5
--> is of type Nat (In Nat1 (Nat5Plus a))Divide (//) by a Nat (Min ...). div 0 is impossible.
Nat.N.toIn nat7 |> Nat.In.div (nat3 |> Nat.N.toMin)
--> Nat 2 of type Nat (In Nat0 (Nat7Plus a))The remainder after division. remainderBy 0 is impossible.
Nat.N.toIn nat7 |> Nat.In.remainderBy (nat3 |> Nat.N.toMin)
--> Nat 1 of type Nat (In Nat0 (Nat7Plus a))If you want other operations like multiply, use dropMax.
Set the minimum lower.
[ Nat.N.toIn nat3, Nat.N.toIn nat4 ]Elm complains:
But all the previous elements in the list are:
Nat (In Nat3 ...)
[ Nat.N.toIn nat3
, Nat.N.toIn nat4 |> Nat.In.lowerMin nat3
]Make it fit into functions with higher maximum.
You should design type annotations as general as possible.
onlyAtMost18 : Nat (In min Nat18)
onlyAtMost18 between3And8 --fineBut once you implement onlyAtMost18, you might use the value in onlyAtMost19.
onlyAtMost18 value =
-- onlyAtMost19 value --error :(
onlyAtMost19
(value |> Nat.In.maxIs nat18 {- works :) -})lowerMin is also handy in those situations.
Convert a Nat (In ...) to a Nat (Min ...).
squareAInNat =
Nat.In.dropMax >> Nat.Min.toPower (nat2 |> Nat.N.toMin)
A
Nat (In ...)from anInt, clamped between a minimum & maximum.Int < minimum,minimumis returnedInt > maximum,maximumis returnedIf you want to handle the cases
< minimum&> maximumexplicitly, useisIntInRange.