Open JanCVanB opened 2 years ago
Makes sense to me! 👍
So I assume the type would be clamp : Num a, Num a, Num a -> Num a
yeah?
Actually, take a look at that second example:
Num.clamp Num.maxU16 Num.minI8 Num.maxI8 == (Num.maxI8 |> Num.toU16)
I'm hoping this function can help #2411 by clamping one type to another's bounds before casting it:
toI8Clamped = \n -> n |> Num.clamp Num.minI8 Num.maxI8 |> Num.toI8
toI8Clamped Num.maxU16 == Num.maxI8
However, if all the types are the same, then a signed minimum bound couldn't be used to clamp an unsigned input, since it's unrepresentable in the unsigned type:
toI8ClampedUgly = \n -> n |> Num.clamp 0 (Num.maxI8 |> Num.toU16) |> Num.toI8
toI8ClampedUgly Num.maxU16 == (Num.maxI8 |> Num.toU16)
Right?
I would prefer clamp to take a single type parameter as suggested in https://github.com/rtfeldman/roc/issues/2439#issuecomment-1027959773, otherwise it feels a little bit too magical IMO
Should this be a builtin?
Inspired by
C++ std::clamp
, #2411, and the imagined verbosity of implementing this in pure Roc.Examples: