标签: active-pattern

F#使用活动模式映射正则表达式匹配

我发现这篇关于使用带有正则表达式的活动模式的有用文章:http: //www.markhneedham.com/blog/2009/05/10/f-regular-expressionsactive-patterns/

文章中使用的原始代码段是:

open System.Text.RegularExpressions

let (|Match|_|) pattern input =
    let m = Regex.Match(input, pattern) in
    if m.Success then Some (List.tl [ for g in m.Groups -> g.Value ]) else None

let ContainsUrl value = 
    match value with
        | Match "(http:\/\/\S+)" result -> Some(result.Head)
        | _ -> None
Run Code Online (Sandbox Code Playgroud)

如果找到至少一个网址以及该网址是什么(如果我正确理解了该网址片段),会告诉您

然后在评论部分Joel建议这个修改:

替代方案,因为给定的组可能是也可能不是成功匹配:

List.tail [ for g in m.Groups -> if g.Success then Some g.Value else None ]
Run Code Online (Sandbox Code Playgroud)

或者,您可以为组添加标签,并希望按名称访问它们:

(re.GetGroupNames()
 |> Seq.map (fun n -> (n, m.Groups.[n]))
 |> Seq.filter (fun …
Run Code Online (Sandbox Code Playgroud)

regex f# f#-interactive active-pattern

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

活动模式和成员约束

对于内联函数,可以创建一个约束,如:

let inline implicit arg =
  ( ^a : (static member op_Implicit : ^b -> ^a) arg)
Run Code Online (Sandbox Code Playgroud)

在参数上要求给定的运算符或成员.是否有基于相似的东西匹配的方法?

我想创建一个活动模式,其中传递给方法的任何参数与内联函数的约束匹配,如上所述触发该函数,其他所有内容都作为一些错误管理的一部分结束.

f# inline constraints active-pattern

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

Scala Extractor with Argument

Scala中是否存在允许提取器采用自定义参数的语法?这个例子有点人为.假设我在整数上有一个二叉搜索树,如果它的值可以被某个自定义值整除,我想匹配当前节点.

使用F#活动模式,我可以执行以下操作:

type Tree =
    | Node of int * Tree * Tree
    | Empty  

let (|NodeDivisibleBy|_|) x t =
    match t with
    | Empty -> None
    | Node(y, l, r) -> if y % x = 0 then Some((l, r)) else None

let doit = function
    | NodeDivisibleBy(2)(l, r) -> printfn "Matched two: %A %A" l r
    | NodeDivisibleBy(3)(l, r) -> printfn "Matched three: %A %A" l r
    | _ -> printfn "Nada"

[<EntryPoint>]
let main args =
    let …
Run Code Online (Sandbox Code Playgroud)

f# scala pattern-matching active-pattern extractor

9
推荐指数
2
解决办法
651
查看次数

在F#3.0中打破活动模式

这个活动模式使用F#2.0编译:

let (|Value|_|) value = // 'a -> 'T option
  match box value with
  | :? 'T as x -> Some x
  | _ -> None
Run Code Online (Sandbox Code Playgroud)

但是,在F#3.0中,发出错误:

活动模式'|值| _ |' 具有包含不由输入确定的类型变量的结果类型.当没有提到结果案例时,常见原因是[sic],例如'let(| A | B |)(x:int)= A x'.这可以通过类型约束来修复,例如'let(| A | B |)(x:int):Choice = A x'

我试过了:

let (|Value|_|) value : 'T option = ...
Run Code Online (Sandbox Code Playgroud)

和:

let (|Value|_|) (value: 'U) = ...
Run Code Online (Sandbox Code Playgroud)

怎么修好?

环境:Visual Studio 2012(RTM)和FSI v11.0.50727.1

编辑:这是一个更简单的repro:

let (|X|) x = unbox x
Run Code Online (Sandbox Code Playgroud)

f# active-pattern f#-3.0 visual-studio-2012

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

试图理解F#活动模式,为什么我可以这样做:

我有一个Dictionary我最初迭代,因此:

myDictionary |> Seq.iter (fun kvp -> doSomething kvp.Key kvp.Value)

后来,我发现我可以使用KeyValue活动模式,并执行此操作:

myDictionary |> Seq.iter (fun (KeyValue (k, v)) -> doSomething k v)

知道活动模式不是某种形式的预处理器指令,我如何能够kvp将lambda中的参数替换为分解它的函数?

f# active-pattern

8
推荐指数
2
解决办法
724
查看次数

在F#中使用布尔函数作为模式鉴别器

我试着谷歌搜索这个,但我找不到一系列的文字引导我到我想做的事情.

我正在尝试解决Project Euler Problem 54,我有这个相当荒谬的功能:

let evaluate hand =
    if isRoyalFlush hand then 9
    elif isStraightFlush hand then 8
    elif isFour hand then 7
    elif isFullHouse hand then 6
    elif isFlush hand then 5
    elif isStraight hand then 4
    elif isThree hand then 3
    elif isTwoPair hand then 2
    elif isPair hand then 1
    else 0
Run Code Online (Sandbox Code Playgroud)

所有isSomething关键字都是采用string array并返回布尔值的函数.使用模式匹配是否有更优雅的方法?

这不起作用:

match true with
| isRoyalFlush hand -> 9
| isStraightFlush hand -> 8
// .. …
Run Code Online (Sandbox Code Playgroud)

f# pattern-matching active-pattern

7
推荐指数
2
解决办法
308
查看次数

在活动模式中使用typeof <_>

鉴于以下设计的活跃模式:

let (|TypeDef|_|) (typeDef:Type) (value:obj) =
  if obj.ReferenceEquals(value, null) then None
  else
    let typ = value.GetType()
    if typ.IsGenericType && typ.GetGenericTypeDefinition() = typeDef then Some(typ.GetGenericArguments())
    else None
Run Code Online (Sandbox Code Playgroud)

下列:

let dict = System.Collections.Generic.Dictionary<string,obj>()
match dict with
| TypeDef typedefof<Dictionary<_,_>> typeArgs -> printfn "%A" typeArgs
| _ -> ()
Run Code Online (Sandbox Code Playgroud)

给出错误:

模式匹配中的意外类型应用程序.预期' - >'或其他令牌.

但这有效:

let typ = typedefof<Dictionary<_,_>>
match dict with
| TypeDef typ typeArgs -> printfn "%A" typeArgs
| _ -> ()
Run Code Online (Sandbox Code Playgroud)

为什么typedefof(或typeof)不允许在这里?

f# active-pattern

5
推荐指数
2
解决办法
1053
查看次数

在discrimated union类型声明中使用活动模式

是否可以在discrimated union类型声明中使用活动模式?

更准确地说,请考虑以下玩具示例:

type T = 
    | A of int
    | B

let (|Negative|_|) t = 
    match t with
    | A n when n < 0 -> Some ()
    | _ -> None

let T_ToString = function
    | Negative () -> "negative!"
    | _ -> "foo!"
Run Code Online (Sandbox Code Playgroud)

现在假设我想覆盖T中的ToString().在T的类型声明中,我不能引用T_ToString,因为T_ToString尚未在那时声明.我无法在ToString()之前移动活动模式和T_ToString,因为此时尚未声明T.但这也不起作用:

type T = 
    | A of int
    | B

    static member (|Negative|_|) t = 
        match t with
        | A n when n < 0 -> Some ()
        | _ -> None

    override this.ToString …
Run Code Online (Sandbox Code Playgroud)

f# discriminated-union active-pattern

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

与AND模式不完全匹配

我在F#中定义了一个表达式树结构,如下所示:

type Num = int
type Name = string
type Expr = 
    | Con of Num
    | Var of Name
    | Add of Expr * Expr
    | Sub of Expr * Expr
    | Mult of Expr * Expr
    | Div of Expr * Expr
    | Pow of Expr * Expr
    | Neg of Expr
Run Code Online (Sandbox Code Playgroud)

我希望能够漂亮打印表达式树,所以我做了以下事情:

let (|Unary|Binary|Terminal|) expr = 
    match expr with
    | Add(x, y) -> Binary(x, y)
    | Sub(x, y) -> Binary(x, y)
    | Mult(x, y) -> Binary(x, y) …
Run Code Online (Sandbox Code Playgroud)

f# pattern-matching active-pattern

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

将部分活动模式作为参数传递?

我正在通过使用活动模式编写递归下降解析器来学习F#.

由于我的所有规则或部分活动模式都需要以不同的方式组合它们,但我对将活动模式作为参数传递的语法感到非常沮丧.

以下示例显示了我遇到的问题:

// Combines two patterns by chaining them.
let (|Chain|_|) (|Pattern1|_|) (* Should I use pipes here? *) (|Pattern2|_|) data =
    match data with
    |Pattern1 result ->
        match result with
        |Pattern2 result2 -> Some result2
        |_ -> None
    |_ -> None 

// Stupid test patterns
let (|IfBiggerThan10ThenDouble|_|) value = if value > 10 then Some (value*2) else None
let (|IfLessThan100ThenDouble|_ |) value = if value < 100 then Some (value*2) else None

match 20 with
// Do I …
Run Code Online (Sandbox Code Playgroud)

f# active-pattern

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