'Can I extend a generic type? in F#
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?
Solution 1:[1]
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.
Solution 2:[2]
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
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 | tranquillity |