如何在 F# 中使用结果验证实现两个字符串的“OR”条件?

huangapple go评论85阅读模式
英文:

How to implement an "OR" condition on two strings with Result Validation in F#?

问题

我正试图在验证字符串时实现一个“或”条件。我失败得很惨。

在F#中给出以下代码:

let isSearchLastName input = 
    let (fn:string,ln:string) = input
    if String.IsNullOrEmpty(ln.Trim()) then Error input else Ok input

let isSearchFirstName input = 
    let (fn:string,ln:string) = input
    if String.IsNullOrEmpty(fn.Trim()) then Error input else Ok input

let validatenamesearch = isSearchLastName ||| isSearchFirstName

let isSearchNameValid = validatenamesearch (m.SearchLastName, m.SearchFirstName) |> Result.Ok

其中,||| 是:

let oorr addSuccess addFailure switch1 switch2 x =
    match (switch1 x),(switch2 x) with
    | Ok s1,Ok s2 -> Ok (addSuccess s1 s2)
    | Error f1,Ok s2 -> Ok (addSuccess f1 s2)
    | Ok s1 ,Error f2 -> Ok (addSuccess s1 f2)
    | Error f1,Error f2 -> Error (addFailure f1 f2)

// 创建一个“或”函数用于验证函数
let (|||) v1 v2 =
    let addSuccess r1 r2 = r1,r2 
    let addFailure s1 s2 = s1,s2
    oorr addSuccess addFailure v1 v2

我试图像下面这样使用它:

if isSearchNameValid then ......

但我得到编译器的投诉:

val isSearchNameValid: Result<Result<((string*string)*(string*string)),((string*string)*(string*string))>,obj>

我希望实现的是一种验证方法,如果任一字符串为空,则结果将成功(带有Ok),然后我可以使用Ok返回的值(如果失败,即两个字符串都为空,则中止进一步处理)。最终,我希望能够使用|||运算符将多个“或”条件链接在一起。

非常感谢您的帮助。

英文:

I am attempting to implement an "or" condition in validating strings. I am failing miserably.

Given the following in F#:

let isSearchLastName  input = let (fn:string,ln:string) = input
                              if String.IsNullOrEmpty(ln.Trim()) then Error input else Ok input

let isSearchFirstName input = let (fn:string,ln:string) = input
                              if String.IsNullOrEmpty(fn.Trim()) then Error input else Ok input

let validatenamesearch = isSearchLastName ||| isSearchFirstName
                                

let isSearchNameValid = validatenamesearch  (m.SearchLastName, m.SearchFirstName) |&gt; Result.Ok

Where, ||| is:

let oorr addSuccess addFailure switch1 switch2 x =
    match (switch1 x),(switch2 x) with
    | Ok s1,Ok s2 -&gt; Ok (addSuccess s1 s2)
    | Error f1,Ok s2  -&gt; Ok (addSuccess f1 s2)
    | Ok s1 ,Error f2 -&gt; Ok (addSuccess s1 f2)
    | Error f1,Error f2 -&gt; Error (addFailure f1 f2)
   
// create a &quot;or&quot; function for validation functions
let (|||) v1 v2 =
    let addSuccess r1 r2 = r1,r2 
    let addFailure s1 s2 = s1,s2
    oorr addSuccess addFailure v1 v2

I am attempting to use the above something like:

if isSearchNameValid then ......

What I am getting is the compiler complaining with:

val isSearchNameValid: Result&lt;Result&lt;((string*string)*(string*string)),((string*string)*(string*string))&gt;,obj&gt;

What I am hoping to achieve is a validation method where should either string be non-empty, the result will be success (with Ok) and I can then use the returned values from the Ok. (or if fails --i.e., neither string is non-empty--then abort further processing). Eventually, I would like to be able to chain together multiple "OR" conditions using the ||| operator.

Any help is most appreciated.

TIA

答案1

得分: 2

我认为这将实现你想要的

```fsharp
let (|||) op1 op2 arg =
    match op1 arg with
        | Ok value -&gt; Ok value
        | Error _ -&gt; op2 arg

let isSearchNameValid =
    isSearchLastName ||| isSearchFirstName

示例:

let john = &quot;John&quot;, &quot;Lennon&quot;
isSearchNameValid john |&gt; printfn &quot;%A&quot;   // Ok (&quot;John&quot;, &quot;Lennon&quot;)

let paul = &quot;Paul&quot;, &quot;&quot;
isSearchNameValid paul |&gt; printfn &quot;%A&quot;   // Ok (&quot;Paul&quot;, &quot;&quot;)

let blank = &quot;&quot;, &quot;&quot;
isSearchNameValid blank |&gt; printfn &quot;%A&quot;  // Error (&quot;&quot;, &quot;&quot;)

<details>
<summary>英文:</summary>

I think this will do what you want:

```fsharp
let (|||) op1 op2 arg =
    match op1 arg with
        | Ok value -&gt; Ok value
        | Error _ -&gt; op2 arg

let isSearchNameValid =
    isSearchLastName ||| isSearchFirstName

Example:

let john = &quot;John&quot;, &quot;Lennon&quot;
isSearchNameValid john |&gt; printfn &quot;%A&quot;   // Ok (&quot;John&quot;, &quot;Lennon&quot;)

let paul = &quot;Paul&quot;, &quot;&quot;
isSearchNameValid paul |&gt; printfn &quot;%A&quot;   // Ok (&quot;Paul&quot;, &quot;&quot;)

let blank = &quot;&quot;, &quot;&quot;
isSearchNameValid blank |&gt; printfn &quot;%A&quot;  // Error (&quot;&quot;, &quot;&quot;)

huangapple
  • 本文由 发表于 2023年6月8日 22:21:44
  • 转载请务必保留本文链接:https://go.coder-hub.com/76432836.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定