我们有这些小的辅助函数。
现在来看问题。
将一些验证器组合成更复杂的验证约束会很好,像这样:
如果只允许使用一个“s”,我们可以考虑将函数合并,这样我们只有一个参数s。由于活动模式匹配函数本质上也是函数,因此应用函数组合运算符>>,但在这里不适用。
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
在函数接口中使用非空字符串的活动模式匹配函数是有效的:
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 中实现呢?
let hi (NonEmptyString s & StartsWithX _) = printfn "Hi %s" s
。但是,你现在的做法看起来不太像F#的典型写法。 - kvblet hi (NonEmptyString (StartsWithX s)) = ...
。但这种方法无法推广到更习惯用法的活动模式。 - kvb