Skip to content

Instantly share code, notes, and snippets.

@TheAngryByrd
Created July 6, 2023 22:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save TheAngryByrd/c8b9c8ebcda3bb162f425bfb281d2e2b to your computer and use it in GitHub Desktop.
Save TheAngryByrd/c8b9c8ebcda3bb162f425bfb281d2e2b to your computer and use it in GitHub Desktop.
F# Computation Expression Method Overload Resolution Ordering
open System.Threading.Tasks
type FooBuilder() =
member _.Return(x) = Task.FromResult(Ok x)
member _.Bind(x, f) : Task<Result<'TResult, 'Error list>> =
task {
let! x = x
match x with
| Ok x -> return! f x
| Error e -> return Error e
}
member _.Source(s: Task<Result<'TResult, 'Error list>>) = s
member _.Source(s: Result<_, _ list>) = Task.FromResult s
[<AutoOpen>]
module LowerPriority =
type FooBuilder with
member _.Source(s: Task<'TResult>) =
task {
let! x = s
return Ok x
}
member _.Source(s: Result<_, _>) =
Task.FromResult(Result.mapError List.singleton s)
[<AutoOpen>]
module HigherPriority =
type FooBuilder with
member _.Source(s: Result<_, _ seq>) = Task.FromResult (Result.mapError List.ofSeq s)
let foo = FooBuilder()
let doit () =
foo {
let! x = Task.FromResult(Ok 1)
let! y = Task.FromResult(2)
let! z = Ok 3
let! a = Error [ "a" ]
let! b = Error "a"
let! b = Error (Seq.singleton "a")
return x + y + z + a + b
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment