F# 有没有一种方法可以在不使用匹配的情况下快速检查已识别的联合值的类型

F# 有没有一种方法可以在不使用匹配的情况下快速检查已识别的联合值的类型,f#,F#,假设我有这种类型: type ResultInfo = | Success | Error of (HttpStatusCode * string) 以及一个返回ResultInfo类型“result”的函数 有没有一种方法可以做到: if result is type Success then ... 因为有时我只是想知道类型和匹配语法可能有点繁重,如果您只需要进行快速检查您可以编写类似Option.isSome的帮助器模块 或将属性/函数附加到类型 type ResultInfo =

假设我有这种类型:

type ResultInfo =
| Success
| Error of (HttpStatusCode * string)
以及一个返回ResultInfo类型“result”的函数

有没有一种方法可以做到:

if result is type Success then ...

因为有时我只是想知道类型和匹配语法可能有点繁重,如果您只需要进行快速检查

您可以编写类似Option.isSome的帮助器模块

或将属性/函数附加到类型

type ResultInfo =
    | Success
    | Error of (HttpStatusCode * string)
    member self.IsSuccess =
        match self with
        | Success -> true
        | Error _ -> false

if result.IsSuccess then
    ...

我总是喜欢显式地指定所有联合案例,这样通过添加新案例将生成编译器警告。如果您仅匹配成功并使用uu处理所有其他联合案例,则可能会导致潜在的错误,因为您没有收到编译器警告,并且可能忘记处理该案例。

您可以编写类似Option的帮助器模块。isSome

或将属性/函数附加到类型

type ResultInfo =
    | Success
    | Error of (HttpStatusCode * string)
    member self.IsSuccess =
        match self with
        | Success -> true
        | Error _ -> false

if result.IsSuccess then
    ...

我总是喜欢显式地指定所有联合案例,这样通过添加新案例将生成编译器警告。如果您仅匹配成功并使用uu处理所有其他联合案例,则可能会导致潜在的错误,因为您没有收到编译器警告,并且可能忘记处理该案例。

您可以使用如下函数比较字符串值:

let sameStrings ut1 ut2 =
    let firstPart (str:string) = str.Split([|' '|])
    let nameString = string >> firstPart
    nameString ut1 = nameString ut2
type MoreSuccess = MoreSuccess of Success //type Success is not defined
if (function Error _ -> true | _ -> false) result then
    printfn "Error"
然后有一个if语句,比如if sameStrings Success a then

下面的示例用法和输出注意:这不会比较实际的错误值,但是如果您想这样做,您应该能够只使用字符串比较:

type ResultInfo =
    | Success
    | Error of (int * string)

let printSameAs ut1 ut2 = 
    printfn "%A - match %A: %b" ut1 ut2 (sameStrings ut1 ut2)

let a = Success
let b = Error (404,"Not Found")

printSameAs a Success
printSameAs b Success
printSameAs a (Error (0,""))
printSameAs b (Error (0,""))
输出:

Success - match Success: true
Error (404, "Not Found") - match Success: false
Success - match Error (0, ""): false
Error (404, "Not Found") - match Error (0, ""): true

您可以将字符串值与如下函数进行比较:

let sameStrings ut1 ut2 =
    let firstPart (str:string) = str.Split([|' '|])
    let nameString = string >> firstPart
    nameString ut1 = nameString ut2
type MoreSuccess = MoreSuccess of Success //type Success is not defined
if (function Error _ -> true | _ -> false) result then
    printfn "Error"
然后有一个if语句,比如if sameStrings Success a then

下面的示例用法和输出注意:这不会比较实际的错误值,但是如果您想这样做,您应该能够只使用字符串比较:

type ResultInfo =
    | Success
    | Error of (int * string)

let printSameAs ut1 ut2 = 
    printfn "%A - match %A: %b" ut1 ut2 (sameStrings ut1 ut2)

let a = Success
let b = Error (404,"Not Found")

printSameAs a Success
printSameAs b Success
printSameAs a (Error (0,""))
printSameAs b (Error (0,""))
输出:

Success - match Success: true
Error (404, "Not Found") - match Success: false
Success - match Error (0, ""): false
Error (404, "Not Found") - match Error (0, ""): true

您不能进行类型测试,因为联合用例不是真正的类型-它是一种联合类型,类似于C中的联合,带有一个标记,表示它是哪种情况

这就是为什么你不能这样做:

let sameStrings ut1 ut2 =
    let firstPart (str:string) = str.Split([|' '|])
    let nameString = string >> firstPart
    nameString ut1 = nameString ut2
type MoreSuccess = MoreSuccess of Success //type Success is not defined
if (function Error _ -> true | _ -> false) result then
    printfn "Error"
因此,您不能执行运行时类型检查。但是,对于实现结构相等的成员,可以直接比较它们。所以

if result = Success then
    printfn "Success!"
else
    printfn "Boo"
是完全有效的,而且清晰易读。 如果您真的想使用If表达式,一种更简洁的方法是定义如下所示的内联函数:

let sameStrings ut1 ut2 =
    let firstPart (str:string) = str.Split([|' '|])
    let nameString = string >> firstPart
    nameString ut1 = nameString ut2
type MoreSuccess = MoreSuccess of Success //type Success is not defined
if (function Error _ -> true | _ -> false) result then
    printfn "Error"

有趣的是,编译器将生成扩展属性,如IsSuccess、IsError,但它们会按预期工作,它们是为了与来自其他语言(如C和VB)的DU进行互操作,不幸的是在F中不可见。

您不能进行类型测试,因为联合用例不是真正的类型-它是一种联合类型,类似于C中的联合,带有一个标记,指示它是哪种情况

这就是为什么你不能这样做:

let sameStrings ut1 ut2 =
    let firstPart (str:string) = str.Split([|' '|])
    let nameString = string >> firstPart
    nameString ut1 = nameString ut2
type MoreSuccess = MoreSuccess of Success //type Success is not defined
if (function Error _ -> true | _ -> false) result then
    printfn "Error"
因此,您不能执行运行时类型检查。但是,对于实现结构相等的成员,可以直接比较它们。所以

if result = Success then
    printfn "Success!"
else
    printfn "Boo"
是完全有效的,而且清晰易读。 如果您真的想使用If表达式,一种更简洁的方法是定义如下所示的内联函数:

let sameStrings ut1 ut2 =
    let firstPart (str:string) = str.Split([|' '|])
    let nameString = string >> firstPart
    nameString ut1 = nameString ut2
type MoreSuccess = MoreSuccess of Success //type Success is not defined
if (function Error _ -> true | _ -> false) result then
    printfn "Error"

有趣的是,编译器将生成扩展属性,如IsSuccess、iError,它们按预期工作,但是,它们是为了与来自其他语言(如C和VB)的DU进行互操作,不幸的是在F中不可见。

因此F编译器本身生成IsSuccess,iError属性-它们在F中是不可访问的。您自己定义它,就像在您的示例中一样,将无法编译,除非您禁用增强功能;奇怪的是,它不能从F访问,这完全有道理!我会使附加的属性而不是函数。但是我在挑剔。所以F编译器本身生成IsSuccess,iError属性——它们在F中是不可访问的。自己定义它,就像在你的例子中一样,除非你禁用增强功能,否则将无法编译;奇怪的是,它不能从F访问,这完全有道理!我会使附加的属性而不是函数。但我在挑剔。