问题描述
我具有各种数值,希望将它们保持在一定范围内:例如列的宽度从10到50(含);或行数从1到100(含1和100)之间。这些值来自我的F#代码外部的进程。
当给定值降到下限以下时,我希望给定该值的最小界限值。 当给定值超出上限时,我希望给定该值的最大界限值。 否则,我会接受给定的值。
例如:
界限= 10到50 –给定值= 3 –结果值= 10
界限= 10到50 –给定值= 200 –结果值= 50
界限= 10到50 –给定值= 32 –结果值= 32
我想出了一些代码,但是我不确定这是不是做得太过分,还是我这样做很愚蠢。 看起来很容易推断其工作原理,但我不确定,无缘无故。
type ValueAndBounds = { Value : int; Lower : int; Upper: int }
let (|TooSmall|TooLarge|CorrectSize|) input =
if input.Value < input.Lower then TooSmall
elif input.Value > input.Upper then TooLarge
else CorrectSize
let keepWithinBounds input =
match input with
| TooSmall -> input.Lower
| TooLarge -> input.Upper
| CorrectSize -> input.Value
type ColumnWidth = ColumnWidth of int
let width = ColumnWidth (keepWithinBounds { Value = 32; Lower = 10; Upper = 50 })
有什么办法可以改善这一点?
对于这种简单的事情,我走得太远了吗(这超出了必要)吗?
是否有更好的方法可以做到这一点?
解决方法
我个人只是定义一个简单的函数,并使用一些局部应用程序,
let keepWithBounds min max value =
if (value < min) then
min
elif (value > max) then
max
else
value
然后您的代码可以执行类似的操作
let handleWidth = keepWithBounds 10 50
let width1 = handleWidth 32
let width2 = handleWidth 60
,
这是我自己的答案,它同时使用活动模式和部分应用程序,并允许通用使用而无需其他类型。
let (|TooSmall|TooLarge|CorrectSize|) (lower,upper,input) =
if input < lower then TooSmall
elif input > upper then TooLarge
else CorrectSize
let keepWithinBounds lowerBound upperBound input =
match (lowerBound,upperBound,input) with
| TooSmall -> lowerBound
| TooLarge -> upperBound
| CorrectSize -> input
type ColumnWidth = ColumnWidth of int
type RowHeight = RowHeight of int
type Temperature = Temperature of float
let createColumnWidth = keepWithinBounds 10 40
let createRowHeight = keepWithinBounds 60 100
let createTemperature = keepWithinBounds 0.0 20.0
let width = ColumnWidth (createColumnWidth 50)
let height = RowHeight (createRowHeight 50)
let temp = Temperature (createTemperature 33.1)
//val width : ColumnWidth = ColumnWidth 40
//val height : RowHeight = RowHeight 60
//val temp : Temperature = Temperature 20.0