3

我将活动模式“表达式”定义如下:

let (|Expression|_|) expression _ = Some(expression)

现在我正在尝试以这种方式使用它:

match () with
| Expression((totalWidth - wLeft - wRight) / (float model.Columns.Count - 0.5)) cw
    when cw <= wLeft * 4. && cw <= wRight * 4. ->
        cw
| Expression((totalWidth - wLeft) / (float model.Columns.Count - .25)) cw
    when cw <= wLeft * 4. && cw > wRight * 4. ->
        cw
| Expression((totalWidth - wRight) / (float model.Columns.Count - .25)) cw
    when cw > wLeft * 4. && cw <= wRight * 4. ->
        cw
| Expression(totalWidth / float model.Columns.Count) cw
    when cw > wLeft * 4. && cw > wRight * 4. ->
        cw
| _ -> System.InvalidProgramException() |> raise

但这会导致“错误 FS0010:模式中出现意外符号 '-'”。那可以修吗?

我想要做的是清楚地写出以下方程的解:

max(wl - cw * .25, 0) + max(wr - cw * .25) + cw * columnCount = ActualWidth

其中 cw 是唯一的变量。

你能提出更好的方法吗?

4

1 回答 1

7

可用作参数化活动模式的参数的表达式语言在某些方面受到限制。据我所知,F# 规范并没有明确说明,但语法表明必须可以将参数表达式解析为pat-param(第 90 页):

拍参数:=
    | 常量
    | 长识
    | [拍参数; ... ; 拍参数]
    | (拍参数, ...,拍参数)
    | 长标识 pat-param
    | pat-param :类型
    | <@ expr @>
    | <@@表达式@@>
    | 无效的

因此,我认为您需要以不同的方式编写模式匹配。您可以将表达式转换为match构造的普通参数并编写如下内容:

match 
  (totalWidth - wLeft - wRight) / (float model.Columns.Count - 0.5),
  (totalWidth - wLeft) / (float model.Columns.Count - .25),
  (totalWidth - wRight) / (float model.Columns.Count - .25)
with
| cw1, _, _ when cw1 <= wLeft * 4. && cw1 <= wRight * 4. -> cw1
| _, cw2, _ when cw2 <= wLeft * 4. && cw2 > wRight * 4. -> cw2
| _, _, cw3 when cw3 > wLeft * 4. && cw3 <= wRight * 4. -> cw3
| _ -> totalWidth / float model.Columns.Count

如果表达式中使用的模式始终相同,您还可以使用活动模式,例如:

let (|Calculate|) w p _ =
  (totalWidth - w) / (float model.Columns.Count - p)

...然后写下类似的东西:

let wDif = wLeft - wRight
match () with
| Calculate wDif 0.5 cw -> cw
| Calculate wLeft 0.25 cw -> cw
// .. etc.
于 2011-05-29T17:05:38.150 回答