如何将复杂的表达式传递给参数化的活动模式? [英] How can I pass complex expression to parametrized active pattern?
问题描述
我将活动模式"Expression"定义如下:
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
但这会导致错误FS0010:模式中出现意外的符号'-'".那可以解决吗?
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
max(wl - cw * .25, 0) + max(wr - cw * .25) + cw * columnCount = ActualWidth
其中cw是唯一变量.
您能提出更好的建议吗?
Can you suggest any better way?
推荐答案
可用作参数化活动模式参数的表达式的语言在某些方面受到限制.据我所知, F#规范并未明确指出,但语法表明必须有可能将自变量表达式解析为pat-param
(第90页):
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
| 长期身份
| [ pat-param ; ...; pat-param ]
| ( pat-param ,..., pat-param )
| 长期身份 pat-param
| pat-param : type
| < @ expr @>
| < @@ expr @@>
|空
pat-param :=
| const
| long-ident
| [ pat-param ; ... ; pat-param ]
| ( pat-param, ..., pat-param )
| long-ident pat-param
| pat-param : type
| <@ expr @>
| <@@ expr @@>
| null
因此,我认为您需要以不同的方式编写匹配的模式.您可以将表达式转换为match
构造的普通参数,并编写如下内容:
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.
这篇关于如何将复杂的表达式传递给参数化的活动模式?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!