如何在F#中模式匹配异常与类型测试?

如何在F#中模式匹配异常与类型测试?,f#,F#,我有一个函数,其中我需要模式匹配(而不是尝试…使用)以下代码段中的异常: module Error = type Codes = | InvalidUser = 0 | InvalidEmail = 1 exception AppException of Codes let errorHandler (e: exn) = // This doesn't work match e with

我有一个函数,其中我需要模式匹配(而不是
尝试…使用
)以下代码段中的异常

module Error =

    type Codes =
        | InvalidUser = 0
        | InvalidEmail = 1

    exception AppException of Codes

    let errorHandler (e: exn) =
        // This doesn't work
        match e with
        | :? AppException as err(code) ->
            code.ToString()
        | _ -> e.Message
errorHandler
是一个通用函数,用于捕获应用程序中的
AppExeption
以及其他未处理的异常


如何将模式匹配与类型测试和解构/检索
代码
作为
AppException
的一部分使用?

要实现您最终想要实现的目标,我在这里做了两个更改:

  • code
    从枚举更改为DU
  • 放弃类型测试,因为F定义的异常不需要它
  • 可能是这样的:

    open System
    
    module Error =
    
        type Codes =
            | InvalidUser
            | InvalidEmail
    
        exception AppException of Codes
    
        let errorHandler (e: exn) =
            match e with
            | AppException codes ->
                match codes with
                | InvalidUser -> "invalid users!"
                | InvalidEmail -> "invalid email!"
            | _ -> e.Message
    
    或者,如果嵌套模式匹配不符合您的要求,您可以在这种情况下将其展平:

    let errorHandler (e: exn) =
        match e with
        | AppException InvalidUser ->
            "invalid user!"
        | AppException InvalidEmail ->
            "invalid email"
        | _ -> e.Message
    
    F#定义的异常是有效的单例区分联合,您可以直接在其上进行模式匹配。这里没有涉及类型测试

    如果
    Codes
    必须保持为枚举,您仍然可以执行第一个代码示例,但是您需要在内部匹配表达式中使用catch-all大小写,因为枚举只是一个
    int

    let errorHandler (e: exn) =
        // This doesn't work
        match e with
        | AppException codes ->
            match codes with
            | Codes.InvalidUser -> "invalid users!"
            | Codes.InvalidEmail -> "invalid email!"
            | _ -> "something else?"
        | _ -> e.Message