8 people like it.

ResultBuilder Computational Expression

Computational Expression for Result<'a, 'b>

 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: 
42: 
43: 
44: 
45: 
46: 
47: 
48: 
49: 
50: 
51: 
52: 
53: 
54: 
55: 
56: 
open System

let ofOption error = function Some s -> Ok s | None -> Error error

type ResultBuilder() =
    member __.Return(x) = Ok x

    member __.ReturnFrom(m: Result<_, _>) = m

    member __.Bind(m, f) = Result.bind f m
    member __.Bind((m, error): (Option<'T> * 'E), f) = m |> ofOption error |> Result.bind f

    member __.Zero() = None

    member __.Combine(m, f) = Result.bind f m

    member __.Delay(f: unit -> _) = f

    member __.Run(f) = f()

    member __.TryWith(m, h) =
        try __.ReturnFrom(m)
        with e -> h e

    member __.TryFinally(m, compensation) =
        try __.ReturnFrom(m)
        finally compensation()

    member __.Using(res:#IDisposable, body) =
        __.TryFinally(body res, fun () -> match res with null -> () | disp -> disp.Dispose())

    member __.While(guard, f) =
        if not (guard()) then Ok () else
        do f() |> ignore
        __.While(guard, f)

    member __.For(sequence:seq<_>, body) =
        __.Using(sequence.GetEnumerator(), fun enum -> __.While(enum.MoveNext, __.Delay(fun () -> body enum.Current)))

let result = new ResultBuilder()

type MyErr = Err1 | Err2

let aa : Result<string, MyErr> = 
    result {
      let! (a: string) = Ok "a string"
      printfn "A: %A" a
    //   let! b = Error Err2
    //   printfn "B: %A" b
      let! c = (Some "c string", Err1)
    //   let! c = (None, Err1)
      printfn "C: %A" c
      let d = if true then a else c
      printfn "D: %A" d
      return d
    }
namespace System
val ofOption : error:'a -> _arg1:'b option -> 'c

Full name: Script.ofOption
val error : 'a
union case Option.Some: Value: 'T -> Option<'T>
val s : 'b
union case Option.None: Option<'T>
Multiple items
type ResultBuilder =
  new : unit -> ResultBuilder
  member Bind : m:'r * f:'s -> 't
  member Bind : (Option<'T> * 'E) * f:'p -> 'q
  member Combine : m:'l * f:'m -> 'n
  member Delay : f:(unit -> 'k) -> (unit -> 'k)
  member For : sequence:seq<'a> * body:('a -> 'b) -> 'c
  member Return : x:'a2 -> 'a3
  member ReturnFrom : m:'a1 -> 'a1
  member Run : f:(unit -> 'j) -> 'j
  member TryFinally : m:'h * compensation:(unit -> unit) -> 'h
  ...

Full name: Script.ResultBuilder

--------------------
new : unit -> ResultBuilder
member ResultBuilder.Return : x:'a2 -> 'a3

Full name: Script.ResultBuilder.Return
val x : 'a2
val __ : ResultBuilder
member ResultBuilder.ReturnFrom : m:'a1 -> 'a1

Full name: Script.ResultBuilder.ReturnFrom
val m : 'a1
member ResultBuilder.Bind : m:'r * f:'s -> 't

Full name: Script.ResultBuilder.Bind
val m : 'r
val f : 's
member ResultBuilder.Bind : (Option<'T> * 'E) * f:'p -> 'q

Full name: Script.ResultBuilder.Bind
val m : Option<'T>
val error : 'E
module Option

from Microsoft.FSharp.Core
val f : 'p
member ResultBuilder.Zero : unit -> 'o option

Full name: Script.ResultBuilder.Zero
member ResultBuilder.Combine : m:'l * f:'m -> 'n

Full name: Script.ResultBuilder.Combine
val m : 'l
val f : 'm
member ResultBuilder.Delay : f:(unit -> 'k) -> (unit -> 'k)

Full name: Script.ResultBuilder.Delay
val f : (unit -> 'k)
type unit = Unit

Full name: Microsoft.FSharp.Core.unit
member ResultBuilder.Run : f:(unit -> 'j) -> 'j

Full name: Script.ResultBuilder.Run
val f : (unit -> 'j)
member ResultBuilder.TryWith : m:'i * h:(exn -> 'i) -> 'i

Full name: Script.ResultBuilder.TryWith
val m : 'i
val h : (exn -> 'i)
member ResultBuilder.ReturnFrom : m:'a1 -> 'a1
val e : exn
member ResultBuilder.TryFinally : m:'h * compensation:(unit -> unit) -> 'h

Full name: Script.ResultBuilder.TryFinally
val m : 'h
val compensation : (unit -> unit)
member ResultBuilder.Using : res:'f * body:('f -> 'g) -> 'g (requires 'f :> IDisposable and 'f : null)

Full name: Script.ResultBuilder.Using
val res : 'f (requires 'f :> IDisposable and 'f : null)
type IDisposable =
  member Dispose : unit -> unit

Full name: System.IDisposable
val body : ('f -> 'g) (requires 'f :> IDisposable and 'f : null)
member ResultBuilder.TryFinally : m:'h * compensation:(unit -> unit) -> 'h
val disp : 'f (requires 'f :> IDisposable and 'f : null)
IDisposable.Dispose() : unit
member ResultBuilder.While : guard:(unit -> bool) * f:(unit -> 'd) -> 'e

Full name: Script.ResultBuilder.While
val guard : (unit -> bool)
val f : (unit -> 'd)
val not : value:bool -> bool

Full name: Microsoft.FSharp.Core.Operators.not
val ignore : value:'T -> unit

Full name: Microsoft.FSharp.Core.Operators.ignore
member ResultBuilder.While : guard:(unit -> bool) * f:(unit -> 'd) -> 'e
member ResultBuilder.For : sequence:seq<'a> * body:('a -> 'b) -> 'c

Full name: Script.ResultBuilder.For
val sequence : seq<'a>
Multiple items
val seq : sequence:seq<'T> -> seq<'T>

Full name: Microsoft.FSharp.Core.Operators.seq

--------------------
type seq<'T> = Collections.Generic.IEnumerable<'T>

Full name: Microsoft.FSharp.Collections.seq<_>
val body : ('a -> 'b)
member ResultBuilder.Using : res:'f * body:('f -> 'g) -> 'g (requires 'f :> IDisposable and 'f : null)
Collections.Generic.IEnumerable.GetEnumerator() : Collections.Generic.IEnumerator<'a>
val enum : Collections.Generic.IEnumerator<'a>
Collections.IEnumerator.MoveNext() : bool
member ResultBuilder.Delay : f:(unit -> 'k) -> (unit -> 'k)
property Collections.Generic.IEnumerator.Current: 'a
val result : ResultBuilder

Full name: Script.result
type MyErr =
  | Err1
  | Err2

Full name: Script.MyErr
union case MyErr.Err1: MyErr
union case MyErr.Err2: MyErr
val aa : obj

Full name: Script.aa
Multiple items
val string : value:'T -> string

Full name: Microsoft.FSharp.Core.Operators.string

--------------------
type string = String

Full name: Microsoft.FSharp.Core.string
val a : string
val printfn : format:Printf.TextWriterFormat<'T> -> 'T

Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.printfn
val c : string
val d : string

More information

Link:http://fssnip.net/7UJ
Posted:6 years ago
Author:Yuriy Habarov
Tags: computation expression , #result , #resultbuilder