Skip to content

Instantly share code, notes, and snippets.

@gusty

gusty/CEs.fsx Secret

Created October 27, 2020 07:17
Show Gist options
  • Save gusty/6cbd8f9dbb2843e7c767e4d7c0fb7a55 to your computer and use it in GitHub Desktop.
Save gusty/6cbd8f9dbb2843e7c767e4d7c0fb7a55 to your computer and use it in GitHub Desktop.
Specialized CE through type alias
#r "nuget: FSharpPlus"
open System
open FSharpPlus
open FSharpPlus.Data
open FSharpPlus.Control
module AsyncResult =
type Monad<'X,'t> = Async<Result<'t,'X>>
let inj = ResultT
let prj = ResultT.run
type Builder () =
member __.ReturnFrom (expr) = expr : Monad<'X,'T>
member __.Return (x: 'T) = prj (result x) : Monad<'X,'T>
member __.Yield (x: 'T) = prj (result x) : Monad<'X,'T>
member __.Bind (p: Monad<'X,'T>, rest: 'T -> Monad<'X,'U>) = prj (inj p >>= ( rest >> inj)) : Monad<'X,'U>
member __.MergeSources (t1: Monad<'X,'T>, t2: Monad<'X,'U>) : Monad<'X,'T * 'U> = Lift2.Invoke tuple2 (inj t1) (inj t2) |> prj
member __.BindReturn (x : Monad<'X,'T>, f: 'T -> 'U) : Monad<'X,'U> = Map.Invoke f (inj x) |> prj
module AsyncChoice =
type Monad<'X,'t> = Async<Choice<'t,'X>>
let inj = ChoiceT
let prj = ChoiceT.run
type Builder () =
member __.ReturnFrom (expr) = expr : Monad<'X,'T>
member __.Return (x: 'T) = prj (result x) : Monad<'X,'T>
member __.Yield (x: 'T) = prj (result x) : Monad<'X,'T>
member __.Bind (p: Monad<'X,'T>, rest: 'T -> Monad<'X,'U>) = prj (inj p >>= ( rest >> inj)) : Monad<'X,'U>
member __.MergeSources (t1: Monad<'X,'T>, t2: Monad<'X,'U>) : Monad<'X,'T * 'U> = Lift2.Invoke tuple2 (inj t1) (inj t2) |> prj
member __.BindReturn (x : Monad<'X,'T>, f: 'T -> 'U) : Monad<'X,'U> = Map.Invoke f (inj x) |> prj
let asyncResult = AsyncResult.Builder()
let asyncChoice = AsyncChoice.Builder()
module AsyncResultT =
type Monad<'X,'t> = ResultT<Async<Result<'t,'X>>>
type Builder () =
member __.ReturnFrom (expr) = expr : Monad<'X,'T>
member __.Return (x: 'T) = result x : Monad<'X,'T>
member __.Yield (x: 'T) = result x : Monad<'X,'T>
member __.Bind (p: Monad<'X,'T>, rest: 'T -> Monad<'X,'U>) = p >>= rest : Monad<'X,'U>
member __.MergeSources (t1: Monad<'X,'T>, t2: Monad<'X,'U>) : Monad<'X,'T * 'U> = Lift2.Invoke tuple2 t1 t2
member __.BindReturn (x : Monad<'X,'T>, f: 'T -> 'U) : Monad<'X,'U> = Map.Invoke f x
member _.Run (x: Monad<'X,'T>) = ResultT.run x
let asyncResultT = AsyncResultT.Builder ()
module AsyncOptionT =
type Monad<'t> = OptionT<Async<option<'t>>>
type Builder () =
member __.ReturnFrom (expr) = expr : Monad<'T>
member __.Return (x: 'T) = result x : Monad<'T>
member __.Yield (x: 'T) = result x : Monad<'T>
member __.Bind (p: Monad<'T>, rest: 'T -> Monad<'U>) = p >>= rest : Monad<'U>
member __.MergeSources (t1: Monad<'T>, t2: Monad<'U>) : Monad<'T * 'U> = Lift2.Invoke tuple2 t1 t2
member __.BindReturn (x : Monad<'T>, f: 'T -> 'U) : Monad<'U> = Map.Invoke f x
member _.Run (x: Monad<'T>) = OptionT.run x
let asyncOptionT = AsyncOptionT.Builder ()
let a : ResultT<Async<Result<int,string>>> = monad {
let! a = result 1
let! b = lift (async {return "2"})
let c = int b
return a + c }
let b : Async<Result<_,string>> = asyncResultT {
let! a = result 1
let! b = lift (async {return "2"})
let c = int b
return a + c }
let c = asyncOptionT {
let! a = result 1
let! b = lift (async {return "2"})
let c = int b
return a + c }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment