Reputation: 12137
I have a DU representing error states:
type ExchangeError =
| NoError
| ServiceUnavailable
| HttpError of HttpStatusCode * string
...
and I have one return type used everywhere:
Result<'a, ExchangeError>
Is there a way for me to add a method to that type that would work like this pseudo-solution:
type Result<'a, ExchangeError> with
member this.GetOrFail
match this with
| Ok data -> data
| Error e -> failwith $"error: {e}"
to be used like this:
let result = myData.GetOrFail
I find myself typing this over and over when doing exploration code and I don't care about handling errors, etc; I want either a result or stop at that point. So, I thought a helper method may be useful.
But how can this be achieved?
Upvotes: 2
Views: 72
Reputation: 17153
There's nothing in GetOrFail
that relies on the error type, so you can just make a generic extension:
type Result<'a, 'err> with
member this.GetOrFail =
match this with
| Ok data -> data
| Error e -> failwith $"error: {e}"
But if you really want this extension to apply only to Result<'a, ExchangeError>
, you can do it with a C#-style extension member:
open System.Runtime.CompilerServices
[<Extension>]
type Extensions() =
[<Extension>]
static member GetOrFail (res : Result<'a, ExchangeError>) =
match res with
| Ok data -> data
| Error e -> failwith $"error: {e}"
In this case, you have to invoke it as a method, rather than a property, but I figure that's still good enough.
Upvotes: 3
Reputation: 1685
I don't think you can add extension methods to a partially constrained generic type like that. Probably the best way is to just use a function:
module ExchangeError =
let getOrFail (x: Result<'a, ExchangeError>) =
match x with
| Ok data -> data
| Error e -> failwith $"error: {e}"
let result = getOrFail myData
Upvotes: 0