Skip to content

Instantly share code, notes, and snippets.

@mausch
Created May 23, 2014 21:38
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mausch/8183177aa88cb1a86720 to your computer and use it in GitHub Desktop.
Save mausch/8183177aa88cb1a86720 to your computer and use it in GitHub Desktop.
open System
type StringToExnClass = StringToExnClass with
static member StringToExn (_: ArgumentNullException) = fun (s: string) -> ArgumentNullException s
static member StringToExn (_: AccessViolationException) = fun (s: string) -> AccessViolationException s
static member StringToExn (_: ArrayTypeMismatchException) = fun (s: string) -> ArrayTypeMismatchException s
// etc (need to wrap all relevant types)
let inline iStringToExn (a: ^a, b: ^b) =
((^a or ^b) : (static member StringToExn: ^b -> (string -> ^b)) b)
let inline strToExn (x: string) : 'a when 'a :> exn = iStringToExn (StringToExnClass, Unchecked.defaultof<'a>) x
let inline failwithe (msg: string) : 'a when 'a :> exn =
let e = iStringToExn (StringToExnClass, Unchecked.defaultof<'a>) msg // to use strToExn here apparently you need to redeclare the static member constraints.
raise e // shouldn't really return 'a
let _ : ArgumentNullException = failwithe "blah"
exception SomeOtherException
let _ : SomeOtherException = failwithe "whee" // does not compile because there is no string -> 'a constructor and SomeOtherException is not part of the StringToExn "typeclass"
@eiriktsarpalis
Copy link

In the end, I came up with this https://gist.github.com/eiriktsarpalis/8feb78f1f2ee7b6bfd02

The implementation is much more trivial than the typeclass approach and is cumbersome for anything other than F# exceptions, but I figured that it is probably easier to actually use and read. Plus, the F# compiler should optimise away any redundant lambdas.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment