如何在F#中声明一般的异常类型

Moh*_*sen 8 generics f# exception

如何定义如下的异常?

exception CustomExn<'TMessage> of 'TMessage list
Run Code Online (Sandbox Code Playgroud)

361*_*615 5

也许你可以从 System.Exception 继承?

type CustomExn<'TMessage> (message:'TMessage list) =
    inherit System.Exception ()  

let test =
    try
        raise (CustomExn["string"] )
    with 
    | :? CustomExn<string> -> "CustomExn of string"
    | :? CustomExn<int> -> "CustomExn of int"
    | _ ->  "Everything else"
Run Code Online (Sandbox Code Playgroud)


Sze*_*zer 5

Exception Definitions根据规范,不确定 F# 是否可行(第 164-165 页)

这也不是一个好的解决方案,因为try with只会ExceptionList<string>在这种情况下捕获,所以没有好的方法使它通用

type ExceptionList<'a>(msgList: 'a list) =
    inherit Exception()
    member __.MessageList = msgList

let mock() = 
    raise <| ExceptionList(["failed"])

try
    mock() //raises ExceptionList<string>
with
    //this catch block won't fire, because it is not generic, it is ExceptionList<obj>
    | :? ExceptionList<_> as exnList -> 
        exnList.MessageList 
        |> List.iter (printfn "%A")
Run Code Online (Sandbox Code Playgroud)

更好的方法是Result<'a,'b list>::

let mock'() = 
    if DateTime.Now.Ticks % 2L = 0L 
    then Ok()
    else Error(["failed"])

let result = mock'()
match result with
| Ok _ -> printfn "Ok!"
| Error (msgList) -> 
      msgList
      |> List.iter (printfn "%A")
Run Code Online (Sandbox Code Playgroud)

添加了类型丢失的解决方法:

type ExceptionList(msgList: obj list) =
    inherit Exception()
    member __.MessageList = msgList

// Here is F# exception definition
exception CustomException of ExceptionList

let failwithMany msgs = 
    raise <| CustomException (ExceptionList(msgs))

let mock() =
    //zero type checking here
    failwithMany[1;2;"a";[];"failed"]

try
    mock()
with
    // exnList is list of objects
    | CustomException exnList ->
        exnList.MessageList 
        |> List.iter (printfn "%A")
Run Code Online (Sandbox Code Playgroud)