标签: active-pattern

在F#模式匹配中拆分代码块以提高可读性

// 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

3
推荐指数
1
解决办法
162
查看次数

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

我将活动模式"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)

f# active-pattern

2
推荐指数
1
解决办法
425
查看次数

重复使用F#活动模式结果

在下面的代码中,我必须为每次迭代重复使用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)

f# active-pattern

2
推荐指数
1
解决办法
215
查看次数

为什么我会使用关键字"inline"作为活动模式?

我仍然无法理解为什么我会将关键字inline用于函数.

它给了我什么,我还没有?

let inline (|Positive|Neutral|Negative|) x =
 match sign x with
 | 1 -> Positive
 | -1 -> Negative
 | _ -> Neutral
Run Code Online (Sandbox Code Playgroud)

f# inline active-pattern

2
推荐指数
1
解决办法
162
查看次数

F#:键入匹配和活动模式

鉴于以下内容:

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)

f# pattern-matching active-pattern

2
推荐指数
1
解决办法
66
查看次数

F#将活动模式匹配为扩展元组

我在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)

f# tuples match active-pattern

1
推荐指数
1
解决办法
439
查看次数

为什么活动模式需要特殊语法?

如果普通函数可以用作模式,则可以节省必须编写琐碎的活动模式,如

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)

为什么在模式中函数调用也不起作用?

编辑2

我发现了一个模棱两可的场景 …

f# pattern-matching active-pattern

1
推荐指数
1
解决办法
188
查看次数

如何部分应用活动模式

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)

f# active-pattern

1
推荐指数
1
解决办法
138
查看次数