Disposable computation builder

Computation builder that provides easy way of constructing IDisposable objects. It supports elegant composition of disposable objects using 'do!' which can be used for example when working with 'IObservable' type.

Copy Source
Copy Link
Tools:

Disposable builder declaration

 1: type DisposableBuilder() =
 2:   member x.Delay(f : unit -> IDisposable) = 
 3:     { new IDisposable with 
 4:         member x.Dispose() = f().Dispose() }
 5:   member x.Bind(d1:IDisposable, f:unit -> IDisposable) = 
 6:     let d2 = f()
 7:     { new IDisposable with 
 8:         member x.Dispose() = d1.Dispose(); d2.Dispose() }
 9:   member x.Return(()) = x.Zero()
10:   member x.Zero() =
11:     { new IDisposable with 
12:         member x.Dispose() = () }
13: 
14: let disposable = DisposableBuilder()

Demo #1: Resetting console colors

 1: // Creates disposable that resets console color when disposed
 2: let resetColor() = 
 3:   let clr = Console.ForegroundColor
 4:   disposable { Console.ForegroundColor <- clr }
 5: 
 6: // Prints 'doing work' in red and resets color back
 7: let demo1() =
 8:   use unwind = resetColor()
 9:   Console.ForegroundColor <- ConsoleColor.Red
10:   printfn "doing work"
11: 
12: demo1()        // Prints 'doing work' in red
13: printfn "done" // Prints 'done' in original color

Demo #2: Composing disposables

 1: // Create two IDisposable objects that do some cleanup
 2: let cleanup1 = disposable { 
 3:   printfn "cleanup #1" }
 4: let cleanup2 = disposable { 
 5:   printfn "cleanup #1" }
 6: 
 7: let demo2() =
 8:   // Dispose of both 'cleanup1' and 'cleanup2' when the
 9:   // method finishes. This is useful for example when working
10:   // with IObservable (to dispose of event registrations)
11:   use d = disposable { 
12:     printfn "cleanup"
13:     do! cleanup1
14:     do! cleanup2 }
15:   printfn "foo"
16: 
17: demo2()
type DisposableBuilder =
  class
    new : unit -> DisposableBuilder
    member Bind : d1:IDisposable * f:(unit -> IDisposable) -> IDisposable
    member Delay : f:(unit -> IDisposable) -> IDisposable
    member Return : unit -> IDisposable
    member Zero : unit -> IDisposable
  end

Full name: Snippet.DisposableBuilder
val x : DisposableBuilder
member DisposableBuilder.Delay : f:(unit -> IDisposable) -> IDisposable

Full name: Snippet.DisposableBuilder.Delay
val f : (unit -> IDisposable)
type unit = Unit

Full name: Microsoft.FSharp.Core.unit

  type: unit
  implements: IComparable
Multiple items
type IDisposable =
  interface
    member Dispose : unit -> unit
  end

Full name: System.IDisposable

--------------------

IDisposable
val x : IDisposable
IDisposable.Dispose() : unit
member DisposableBuilder.Bind : d1:IDisposable * f:(unit -> IDisposable) -> IDisposable

Full name: Snippet.DisposableBuilder.Bind
val d1 : IDisposable
val d2 : IDisposable
member DisposableBuilder.Return : unit -> IDisposable

Full name: Snippet.DisposableBuilder.Return
member DisposableBuilder.Zero : unit -> IDisposable
member DisposableBuilder.Zero : unit -> IDisposable

Full name: Snippet.DisposableBuilder.Zero
val disposable : DisposableBuilder

Full name: Snippet.disposable
val resetColor : unit -> IDisposable

Full name: Snippet.resetColor
val clr : ConsoleColor

  type: ConsoleColor
  inherits: Enum
  inherits: ValueType
type Console =
  class
    static member BackgroundColor : System.ConsoleColor with get, set
    static member Beep : unit -> unit
    static member Beep : int * int -> unit
    static member BufferHeight : int with get, set
    static member BufferWidth : int with get, set
    static member CapsLock : bool
    static member Clear : unit -> unit
    static member CursorLeft : int with get, set
    static member CursorSize : int with get, set
    static member CursorTop : int with get, set
    static member CursorVisible : bool with get, set
    static member Error : System.IO.TextWriter
    static member ForegroundColor : System.ConsoleColor with get, set
    static member In : System.IO.TextReader
    static member InputEncoding : System.Text.Encoding with get, set
    static member KeyAvailable : bool
    static member LargestWindowHeight : int
    static member LargestWindowWidth : int
    static member MoveBufferArea : int * int * int * int * int * int -> unit
    static member MoveBufferArea : int * int * int * int * int * int * char * System.ConsoleColor * System.ConsoleColor -> unit
    static member NumberLock : bool
    static member OpenStandardError : unit -> System.IO.Stream
    static member OpenStandardError : int -> System.IO.Stream
    static member OpenStandardInput : unit -> System.IO.Stream
    static member OpenStandardInput : int -> System.IO.Stream
    static member OpenStandardOutput : unit -> System.IO.Stream
    static member OpenStandardOutput : int -> System.IO.Stream
    static member Out : System.IO.TextWriter
    static member OutputEncoding : System.Text.Encoding with get, set
    static member Read : unit -> int
    static member ReadKey : unit -> System.ConsoleKeyInfo
    static member ReadKey : bool -> System.ConsoleKeyInfo
    static member ReadLine : unit -> string
    static member ResetColor : unit -> unit
    static member SetBufferSize : int * int -> unit
    static member SetCursorPosition : int * int -> unit
    static member SetError : System.IO.TextWriter -> unit
    static member SetIn : System.IO.TextReader -> unit
    static member SetOut : System.IO.TextWriter -> unit
    static member SetWindowPosition : int * int -> unit
    static member SetWindowSize : int * int -> unit
    static member Title : string with get, set
    static member TreatControlCAsInput : bool with get, set
    static member WindowHeight : int with get, set
    static member WindowLeft : int with get, set
    static member WindowTop : int with get, set
    static member WindowWidth : int with get, set
    static member Write : bool -> unit
    static member Write : char -> unit
    static member Write : char [] -> unit
    static member Write : float -> unit
    static member Write : decimal -> unit
    static member Write : float32 -> unit
    static member Write : int -> unit
    static member Write : uint32 -> unit
    static member Write : int64 -> unit
    static member Write : uint64 -> unit
    static member Write : obj -> unit
    static member Write : string -> unit
    static member Write : string * obj -> unit
    static member Write : string * obj [] -> unit
    static member Write : string * obj * obj -> unit
    static member Write : char [] * int * int -> unit
    static member Write : string * obj * obj * obj -> unit
    static member Write : string * obj * obj * obj * obj -> unit
    static member WriteLine : unit -> unit
    static member WriteLine : bool -> unit
    static member WriteLine : char -> unit
    static member WriteLine : char [] -> unit
    static member WriteLine : decimal -> unit
    static member WriteLine : float -> unit
    static member WriteLine : float32 -> unit
    static member WriteLine : int -> unit
    static member WriteLine : uint32 -> unit
    static member WriteLine : int64 -> unit
    static member WriteLine : uint64 -> unit
    static member WriteLine : obj -> unit
    static member WriteLine : string -> unit
    static member WriteLine : string * obj -> unit
    static member WriteLine : string * obj [] -> unit
    static member WriteLine : char [] * int * int -> unit
    static member WriteLine : string * obj * obj -> unit
    static member WriteLine : string * obj * obj * obj -> unit
    static member WriteLine : string * obj * obj * obj * obj -> unit
  end

Full name: System.Console
property Console.ForegroundColor: ConsoleColor
val demo1 : unit -> unit

Full name: Snippet.demo1
val unwind : IDisposable
type ConsoleColor =
  | Black = 0
  | DarkBlue = 1
  | DarkGreen = 2
  | DarkCyan = 3
  | DarkRed = 4
  | DarkMagenta = 5
  | DarkYellow = 6
  | Gray = 7
  | DarkGray = 8
  | Blue = 9
  | Green = 10
  | Cyan = 11
  | Red = 12
  | Magenta = 13
  | Yellow = 14
  | White = 15

Full name: System.ConsoleColor

  type: ConsoleColor
  inherits: Enum
  inherits: ValueType
field ConsoleColor.Red = 12
val printfn : Printf.TextWriterFormat<'T> -> 'T

Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.printfn
val cleanup1 : IDisposable

Full name: Snippet.cleanup1
val cleanup2 : IDisposable

Full name: Snippet.cleanup2
val demo2 : unit -> unit

Full name: Snippet.demo2
val d : IDisposable

More information

Link: http://fssnip.net/2s
Posted: 3 years ago
Author: Tomas Petricek (website)
Tags: disposable, computation builder, monad, rx, reactive