简体   繁体   中英

How to declare a generic exception type in F#

如何定义如下异常?

exception CustomExn<'TMessage> of 'TMessage list

Maybe you can just inherit from 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"

Not sure it is possible with F# Exception Definitions according to specs (page 164-165)

This one also NOT A GOOD SOLUTION because try with will only catch ExceptionList<string> in this case so there is no good way to make it generic

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")

The better way though: 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")

Added There is a workaround with type loss:

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")

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM