3

我们有这个小辅助函数

open System

let (|NonEmptyString|) value =
    if String.IsNullOrEmpty value
    then failwith "String must be non-empty."
    else value

let (|StartsWithX|) (value:string) =
    if value.StartsWith("X") |> not
    then failwith "String must start with X."
    else value

在函数接口中使用主动模式匹配函数 NonEmptyString 可以正常工作:

let hi (NonEmptyString s) = printfn "Hi %s" s

hi "X"  // Hi X
hi ""   // System.Exception: String must be non-empty.

现在来解决问题。

将一些验证器组合在一起作为更复杂的验证约束会很好,就像这样

let hi (NonEmptyString s  &  StartsWithX s) = printfn "Hi %s" s
// error FS0038: 's' is bound twice in this pattern

如果只允许一个 's',我们可以考虑组合这些函数,这样我们就只有一个参数 s。并且因为活动模式匹配函数当然是函数,所以应用函数组合运算符 >> 但它不适合这里。

let hi (NonEmptyString >> StartsWithX s) = printfn "Hi %s" s
// error FS0010: Unexpected infix operator in pattern

问题是,我们如何才能做到这一点(在 F# 4.0 中)?

4

1 回答 1

0

正如@kvb 评论的那样,通配符 _ 有助于 AND 情况

// AND
let hi (NonEmptyString _  &  StartsWithX s) = printfn "Hi %s" s

OR 案例与两个 's' 绑定一起使用

// OR
let hi (NonEmptyString s  |  StartsWithX s) = printfn "Hi %s" s
// The logic here makes less sense. It's kept simple with the given helper functions from above.  

笔记:

这只是为了在函数接口上以描述性的方式尝试将 Active Pattern Matching 组合为代码契约。

这可以看作是对 Active Pattern Matching 的使用或误用(惯用的 F# 与否),这是您的选择!

于 2016-01-06T08:34:57.517 回答