3 people like it.
Like the snippet!
Attempt to implement a tail calling exception handling combinator
See also https://fslang.uservoice.com/forums/245727-f-language/suggestions/6536829-implement-ocaml-s-new-match-exception-syntax
1:
2:
3:
4:
5:
6:
7:
|
let inline matchExn (f : 'T -> 'S) (t : 'T) (onSuccess : 'S -> 'R) (onException : exn -> 'R) : 'R =
let mutable exn : System.Exception = null
let mutable s = Unchecked.defaultof<'S>
try s <- f t with e -> exn <- e // e cannot be null
if obj.ReferenceEquals(exn, null) then onSuccess s
else
onException exn
|
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
|
let test () =
matchExn (fun i -> 1 / i) 0
(fun r -> string r)
(fun e -> e.Message)
// Codegen (Release build)
//
//public static string test2()
//{
// Exception ex = null;
// int r = 0;
// try
// {
// r = 1 / 0;
// }
// catch (object arg_0D_0)
// {
// Exception ex2 = (Exception)arg_0D_0;
// ex = ex2;
// }
// if (object.ReferenceEquals(ex, null))
// {
// return Exn.onSuccess@38-1(r);
// }
// return ex.Message;
//}
|
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
|
let countIters (f : int -> bool) =
let rec aux i =
matchExn f i
(function true -> aux (i+1) | false -> i)
(fun _ -> i)
aux 0
// Codegen (Release build)
//
//public static int countIters(FSharpFunc<int, bool> f)
//{
// return Exn.aux@54(f, 0);
//}
//internal static int aux@54(FSharpFunc<int, bool> f, int i)
//{
// Exception objA = null;
// bool b = false;
// try
// {
// b = f.Invoke(i);
// }
// catch (object arg_11_0)
// {
// Exception ex = (Exception)arg_11_0;
// objA = ex;
// }
// if (object.ReferenceEquals(objA, null))
// {
// return Exn.onSuccess@38-2(f, i, b);
// }
// return i;
//}
|
val matchExn : f:('T -> 'S) -> t:'T -> onSuccess:('S -> 'R) -> onException:(exn -> 'R) -> 'R
Full name: Script.matchExn
val f : ('T -> 'S)
val t : 'T
val onSuccess : ('S -> 'R)
val onException : (exn -> 'R)
type exn = System.Exception
Full name: Microsoft.FSharp.Core.exn
Multiple items
val mutable exn : System.Exception
--------------------
type exn = System.Exception
Full name: Microsoft.FSharp.Core.exn
namespace System
Multiple items
type Exception =
new : unit -> Exception + 2 overloads
member Data : IDictionary
member GetBaseException : unit -> Exception
member GetObjectData : info:SerializationInfo * context:StreamingContext -> unit
member GetType : unit -> Type
member HelpLink : string with get, set
member InnerException : Exception
member Message : string
member Source : string with get, set
member StackTrace : string
...
Full name: System.Exception
--------------------
System.Exception() : unit
System.Exception(message: string) : unit
System.Exception(message: string, innerException: exn) : unit
val mutable s : 'S
module Unchecked
from Microsoft.FSharp.Core.Operators
val defaultof<'T> : 'T
Full name: Microsoft.FSharp.Core.Operators.Unchecked.defaultof
val e : exn
type obj = System.Object
Full name: Microsoft.FSharp.Core.obj
System.Object.ReferenceEquals(objA: obj, objB: obj) : bool
val test : unit -> string
Full name: Script.test
val i : int
val r : int
Multiple items
val string : value:'T -> string
Full name: Microsoft.FSharp.Core.Operators.string
--------------------
type string = System.String
Full name: Microsoft.FSharp.Core.string
property System.Exception.Message: string
val countIters : f:(int -> bool) -> int
Full name: Script.countIters
val f : (int -> bool)
Multiple items
val int : value:'T -> int (requires member op_Explicit)
Full name: Microsoft.FSharp.Core.Operators.int
--------------------
type int = int32
Full name: Microsoft.FSharp.Core.int
--------------------
type int<'Measure> = int
Full name: Microsoft.FSharp.Core.int<_>
type bool = System.Boolean
Full name: Microsoft.FSharp.Core.bool
val aux : (int -> int)
More information