如何将复杂表达式传递给参数化活动模式?

发布于 2024-11-10 01:59:24 字数 1017 浏览 0 评论 0原文

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

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 是唯一的变量。

你能建议更好的方法吗?

I defined the active pattern "Expression" as follows:

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

Now I'm trying to use it in this way:

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

But this results in "error FS0010: Unexpected symbol '-' in pattern". Is that fixable?

What am I trying to do is to write clearly a solution to the following equation:

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

where cw is the only variable.

Can you suggest any better way?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

狼性发作 2024-11-17 01:59:24

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

pat-param :=
    |常量
    | 长标识
    | [ pat-param ; ...; pat-param ]
    | (帕特参数,...,帕特参数
    | long-ident pat-param
    | pat-param类型
    | <@ expr @>
    | <@@ 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.

The langauge of expressions that can be used as arguments for parameterized active patterns is limited in some ways. As far as I can tell, the F# specification doesn't say that explicitly, but the grammar suggests that it must be possible to parse the argument expression as pat-param (page 90):

pat-param :=
    | const
    | long-ident
    | [ pat-param ; ... ; pat-param ]
    | ( pat-param, ..., pat-param )
    | long-ident pat-param
    | pat-param : type
    | <@ expr @>
    | <@@ expr @@>
    | null

So, I think you'll need to write your pattern matching differently. You could turn the expressions into ordinary arguments of the match construct and write something like this:

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

If the pattern used in the expression is always the same, you could also use active pattern like:

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

... and then write something like:

let wDif = wLeft - wRight
match () with
| Calculate wDif 0.5 cw -> cw
| Calculate wLeft 0.25 cw -> cw
// .. etc.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文