-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathresource.ml
41 lines (37 loc) · 1.29 KB
/
resource.ml
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
34
35
36
37
38
39
40
41
(*
resource.ml -- closeable and composable resource management
*)
open Dsl
include Instances.ResourceInstances
(* make a r -- acquire resource `a` in IO, and encode how to release it
* with function `r` *)
let make (acq : 'a io) (rel : 'a -> unit io) : 'a resource = Allocate (acq, rel)
(* use u r -- apply function `u` a resource then release it;
* compiles a resource program down to IO *)
let rec use : type a b. (a -> b io) -> a resource -> b io =
fun u r ->
match r with
| Allocate (acquire, release) ->
IO.(
acquire >>= fun a ->
(* handle failure during use to ensure resource release *)
let action =
handle_error_with (fun e -> release a *> raise_error e) (u a)
in
action <* release a)
| RBind (f, res) -> (
match res with
| Allocate (acquire, release) ->
IO.(
acquire >>= fun a ->
let action =
handle_error_with
(fun e -> release a *> raise_error e)
(use u (f a))
in
action <* release a)
| RBind (g, res') -> use u (RBind (g >=> f, res'))
| RPure a -> use u (f a))
| RPure a -> u a
(* use' r -- acquire and release resource with a no-op `u` action *)
let use' : type a. a resource -> a io = fun r -> use IO.pure r