//@NO-IMPLICIT-PRELUDE //! A `Disposable` abstracts over different kinds of resources. let { IO, wrap, flat_map } = import! std.io.prim let { Bool } = import! std.types /// A resource that has to be released after use, for example a file handle or a /// database connection. #[implicit] type Disposable a = { /// Disposes of `a`, releasing the resources it manages. Calling this function /// a second time (or more) has no effect. dispose : a -> IO (), /// Indicates if `a` has been disposed, meaning that `dispose` has been called /// at least once. is_disposed : a -> Bool } let dispose ?disposable : [Disposable a] -> a -> IO () = disposable.dispose let is_disposed ?disposable : [Disposable a] -> a -> Bool = disposable.is_disposed /// Calls `action` with `disposable` and disposes `disposable` afterwards. Returns /// the result of `action`, unless disposing `disposable` fails. let using disposable action : forall r . [Disposable a] -> a -> (a -> IO r) -> IO r = let result = action disposable do _ = dispose disposable result { Disposable, dispose, is_disposed, using, }