clamp function in base
Herbert Valerio Riedel
hvr at gnu.org
Sat Aug 15 09:57:43 UTC 2020
> It seems to me that base is missing the very standard function `clamp ::
> Ord a => a -> a -> a -> a`:
>
> ```haskell
> clamp :: Ord a => a -> a -> a -> a
> clamp low high = min high .max low
> ```
>
> I propose it be added to Data.Ord. It's useful, generic, and non-trivial to
> get right (the "big" number goes with "min" -- causes me cognitive
> dissonance every time.)
I'm -1 on the proposed type-signature.
For one, while the motivation mentions cognitive overhead, it's ironic
that the proposed
:: Ord a => a -> a -> a -> a
with three `a`-typed parameters whose grouping/semantics is all but
obvious if you merely see the type-signature without knowing its
implementation is itself a source of cognitive overhead IMO.
On the other hand, there are already related functions taking
lower/upper bounds defined by the Haskell Report, see
https://www.haskell.org/onlinereport/haskell2010/haskellch19.html#x27-22500019
and so it'd help to kill two birds with one stone by align the proposed
`clamp` with the precedent established by the pre-existing functions in
Data.Ix, such as
,----
| class Ord a => Ix a where
|
| range :: (a, a) -> [a]
| The list of values in the subrange defined by a bounding pair.
|
| index :: (a, a) -> a -> Int
| The position of a subscript in the subrange.
|
| inRange :: (a, a) -> a -> Bool
| Returns True the given subscript lies in the range defined the bounding pair.
|
| rangeSize :: (a, a) -> Int
| The size of the subrange defined by a bounding pair.
`----
So by grouping the type-signature like
clamp :: Ord a => (a,a) -> a -> a
or even
clamp :: Ord a => a -> (a,a) -> a
it becomes a lot more obvious which parameters are the bounds and which
is the subject it's operating upon and it's IMO less error-prone as
there's now less risk to accidentally swap parameters around.
Moreover, this turns `clamp` into a function taking two parameters,
thereby allowing `clamp` to be used as infix operator
(lower,upper) `clamp` x
Having lower/upper bounds represented as tuple also makes it easier to
define constants denoting the bounds, c.f.
| ... = f (clamp int7Bounds x) ...
| where
| int7Bounds = (0,127)
Long story short, I'm -1 on the proposed type-signature; I'm
not against using a type-signature which groups the bounds-parameter
into a tuple in alignment with the "Data.Ix" API.
-- hvr
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 227 bytes
Desc: not available
URL: <http://mail.haskell.org/pipermail/libraries/attachments/20200815/2dca7584/attachment.sig>
More information about the Libraries
mailing list