// Standard pattern matching.
let Foo x =
match x with
| 1 ->
// ... lots of code, only evaluated if x == 1
| 2 ->
// ... lots of code, only evaluated if x == 2
// Standard pattern matching separated out, causing exception.
let Bar x =
let valueOne = //... lots of code, evaluated always. Exception if value <> 1.
let valueTwo = //... lots of code, evaluated always. Exception if value <> 2.
match …Run Code Online (Sandbox Code Playgroud) f# pattern-matching lazy-evaluation code-readability active-pattern
我将活动模式"Expression"定义如下:
let (|Expression|_|) expression _ = Some(expression)
Run Code Online (Sandbox Code Playgroud)
现在我试图以这种方式使用它:
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 <= …Run Code Online (Sandbox Code Playgroud) 在下面的代码中,我必须为每次迭代重复使用Active Pattern结果三次.即
match tree.Parent, postion with
Run Code Online (Sandbox Code Playgroud)
我发现我可以保存活动模式结果.即
let pos = ((|Root|Nil|Single|First|Inner|Last|Unknown|) (tree.Parent, position))
Run Code Online (Sandbox Code Playgroud)
我无法弄清楚的是,是否可以在匹配语句中使用活动模式结果.即
match pos with
| ??? -> printf "("
Run Code Online (Sandbox Code Playgroud)
问题是可以在匹配语句中使用保存的活动模式结果吗?
如果是这样,怎么样?如果没有,需要解释它,以便逻辑上有意义.
为什么不这样做的例子.即语言规范,语法糖,不应该允许绑定活动模式结果,ExprItems与PatItems
我查看了F#2.0语言规范(2010年4月) http://research.microsoft.com/en-us/um/cambridge/projects/fsharp/manual/spec.html#_Toc270597500
但我没有认出任何可以证实答案的东西.
编辑
如果我将代码更改为
let pos = (|Root|Nil|Single|First|Inner|Last|Unknown|) (tree.Parent, position)
match pos with
| Choice1Of7 (tree.Parent, position) -> printf "("
| _ -> ()
Run Code Online (Sandbox Code Playgroud)
我在Choice1Of7之后得到以下错误(tree.Parent,position):
该表达式应该具有类型单位,但这里有类型'a*'b
正如布莱恩建议的那样
match pos with
| Choice1Of7 () -> printf "("
| _ -> ()
Run Code Online (Sandbox Code Playgroud)
结束编辑
注意:我在下面尝试了这个代码,但我找到了一个更好的算法来解决它的问题.
// An F# function to print a CommonTree as an s-expression
// …Run Code Online (Sandbox Code Playgroud) 我仍然无法理解为什么我会将关键字inline用于函数.
它给了我什么,我还没有?
let inline (|Positive|Neutral|Negative|) x =
match sign x with
| 1 -> Positive
| -1 -> Negative
| _ -> Neutral
Run Code Online (Sandbox Code Playgroud) 鉴于以下内容:
type IFruit = interface end
type Avocado = { color : string; age : int } interface IFruit
let (|AvocadoTexture|) (a : Avocado) = if a.age < 7 then "firm" else "mushy"
Run Code Online (Sandbox Code Playgroud)
...为什么这样做:
let texture (f : IFruit) =
match f with
| :? Avocado as a -> if a.age < 7 then "firm" else "mushy"
| _ -> String.Empty
Run Code Online (Sandbox Code Playgroud)
......但不是吗?
let texture (fruit : IFruit) =
match fruit with
| AvocadoTexture t -> t // "The type IFruit …Run Code Online (Sandbox Code Playgroud) 我在diff中使用红色波形在diff中得到以下错误.
Type mismatch. Expecting a Range -> Choice but given a Range * Range -> Choice
是否有某种类型的注释我可以添加到SubSet匹配,所以我不必使用fst和snd?如果没有,是否有意支持这种语法?
type Range = {min : int64; max : int64}
let (|Before|After|BeforeOverlap|AfterOverlap|SuperSet|SubSet|) (x, y) =
if x.min > y.max then After
elif x.min >= y.min then
if x.max <= y.max then SubSet
else AfterOverlap
elif x.max < y.min then Before
elif x.max <= y.max then BeforeOverlap
else SuperSet
let useOldx x xe ye = ()
let diff (xe:IEnumerator<Range>) (ye:IEnumerator<Range>) =
match xe.Current, ye.Current with …Run Code Online (Sandbox Code Playgroud) 如果普通函数可以用作模式,则可以节省必须编写琐碎的活动模式,如
let (|NotEmpty|_|) s = Seq.tryPick Some s
Run Code Online (Sandbox Code Playgroud)
并且假设允许
let s = seq []
match s with
| Seq.tryPick Some -> ...
| _ -> //empty
Run Code Online (Sandbox Code Playgroud)
这将使函数更具可重用性,无需使用匹配的"模式化"函数:
let f x = if x then Some() else None
let (|F|_|) = f
Run Code Online (Sandbox Code Playgroud)
我知道活动模式可以被称为函数,因此可以通过仅定义模式来简化前面的示例.但是,放弃特殊模式语法简化了这一点.
特殊语法的原因是什么?
在下文中,活动模式会影响文字.
[<Literal>]
let X = 1
let (|X|_|) x = if x = 0 then Some() else None
match 0 with //returns true
| X -> true
| _ -> false
Run Code Online (Sandbox Code Playgroud)
为什么在模式中函数调用也不起作用?
我发现了一个模棱两可的场景 …
NuGetFsharpx.Extras包公开了用于正则表达式匹配的活动模式,限定为Fsharpx.Text.Regex.Match.
第一个参数是 BCL 中的 RegexOptions 值。
而不必写:
let someFunc =
| Match RegexOptions.None "...pattern 1..." matches -> ...
| Match RegexOptions.None "...pattern 2..." matches -> ...
| Match RegexOptions.None "...pattern 3..." matches -> ...
...
Run Code Online (Sandbox Code Playgroud)
我希望可以改为(使用修改后的Match'活动模式):
let someFunc =
| Match' "...pattern 1..." matches -> ...
| Match' "...pattern 2..." matches -> ...
| Match' "...pattern 3..." matches -> ...
...
Run Code Online (Sandbox Code Playgroud)
Match'我想出的一种可能的定义是:
let (|Match'|_|) pattern =
function
| Match RegexOptions.None pattern …Run Code Online (Sandbox Code Playgroud)