我发现这篇关于使用带有正则表达式的活动模式的有用文章: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建议这个修改:
替代方案,因为给定的组可能是也可能不是成功匹配:
Run Code Online (Sandbox Code Playgroud)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 …
对于内联函数,可以创建一个约束,如:
let inline implicit arg =
( ^a : (static member op_Implicit : ^b -> ^a) arg)
Run Code Online (Sandbox Code Playgroud)
在参数上要求给定的运算符或成员.是否有基于相似的东西匹配的方法?
我想创建一个活动模式,其中传递给方法的任何参数与内联函数的约束匹配,如上所述触发该函数,其他所有内容都作为一些错误管理的一部分结束.
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#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) 我有一个Dictionary我最初迭代,因此:
myDictionary |> Seq.iter (fun kvp -> doSomething kvp.Key kvp.Value)
后来,我发现我可以使用KeyValue活动模式,并执行此操作:
myDictionary |> Seq.iter (fun (KeyValue (k, v)) -> doSomething k v)
知道活动模式不是某种形式的预处理器指令,我如何能够kvp将lambda中的参数替换为分解它的函数?
我试着谷歌搜索这个,但我找不到一系列的文字引导我到我想做的事情.
我正在尝试解决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) 鉴于以下设计的活跃模式:
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)不允许在这里?
是否可以在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#中定义了一个表达式树结构,如下所示:
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#.
由于我的所有规则或部分活动模式都需要以不同的方式组合它们,但我对将活动模式作为参数传递的语法感到非常沮丧.
以下示例显示了我遇到的问题:
// 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)