可以在一行中优化模式匹配代码段



我想知道是否有一种方法可以编写这一行而无需将H到Calcvol函数两次?

| h :: t when (h |> calcVol) > maxVol -> maxLoop t (h |> calcVol) 

其中H是包含三个维度的元组,Calcvol返回浮点值。

我知道我可以明确将Vol值定义为:

| h :: t -> let vol = calcVol h if vol > maxVol then...

我想知道是否有一种方法可以在一行中做得很好?

如果vol的所有用途都在箭头之前,则可以这样做:

| h :: t when let vol = (h |> calcVol) in vol > maxVol -> // Something

但是,箭头左侧的when子句中的let分配不会延伸到右侧。演示:

let f x = x + 5
let l = [1; 2]
match l with
| a :: b when let y = f a in y = 6 -> "Six"
| _ -> "Other"

这有效,并返回"Six"。但是:

let f x = x + 5
let l = [1; 2]
match l with
| a :: b when let y = f a in y = 6 -> sprintf "Six = %d" y
| _ -> "Other"

这确实不工作,产生错误:

错误FS0039:未定义值或构造函数'y'

很遗憾,您不能拥有想要的单行版本,并且必须采用更长的方法(使用let,然后是if,正如您在答案的后半部分)。

使用有效模式的解决方案可能看起来像这样:

let calcVol v = v
let (|MaxVol|) maxVol = function
| [] -> (maxVol, [])
| h :: t -> ((max (calcVol h) maxVol), t)
let rec maxLoop list m =
    match list with
    | [] -> m
    | MaxVol m (c, t) -> maxLoop t c
let vs = [ -1; 42; 3 ]
maxLoop vs System.Int32.MinValue // 42

更高可读性的另一种可能性可能是首先计算体积(例如,通过map Ping),然后找到最大值。没有完整的代码很难分辨...

最新更新