Reputation: 37045
I want to create an object with this interface in F#:
namespace JWT
{
/// <summary>
/// Provides JSON Serialize and Deserialize. Allows custom serializers used.
/// </summary>
public interface IJsonSerializer
{
/// <summary>
/// Serialize an object to JSON string
/// </summary>
/// <param name="obj">object</param>
/// <returns>JSON string</returns>
string Serialize(object obj);
/// <summary>
/// Deserialize a JSON string to typed object.
/// </summary>
/// <typeparam name="T">type of object</typeparam>
/// <param name="json">JSON string</param>
/// <returns>Strongly-typed object</returns>
T Deserialize<T>(string json);
}
}
I have tried using an object expression but the generic Deserialize
method is tripping me up:
let serializer =
{
new JWT.IJsonSerializer
with
member this.Serialize (o : obj) =
failwith "Not implemented"
member this.Deserialize (json : string) =
let decoded : Result<'t, string> =
Decode.fromString payloadDecoder json
match decoded with
| Result.Ok (o : 't) ->
o
| Result.Error error ->
failwith error
}
The error is:
This code is not sufficiently generic. The type variable 'a could not be generalized because it would escape its scope
How can I implement this?
$ dotnet --version
3.1.300
Upvotes: 3
Views: 156
Reputation: 12577
We can deal with this error by annotating the member. This way the type system will have enough information to fully discern what is going on.
If I tweak your code slightly, I'm able to get it to compile:
open Thoth.Json
type IJsonSerializer =
abstract member Serialize : o:obj -> string
abstract member Deserialize<'a> : json:string -> 'a
type Json () =
let payloadDecoder : Decoder<'a> =
fun _ -> failwith "not impl."
interface IJsonSerializer with
member this.Serialize (o : obj) : string =
failwith "not impl."
member this.Deserialize<'a> (json : string) : 'a =
match Decode.fromString payloadDecoder json with
| Ok (o : 'a) -> o
| Error error -> failwith error
By fully annotating the Deserialize
member the type system should now be satisfied.
A couple things to note:
IJsonSerializer
interface so my code could compile. Though it's not necessary for your final result.payloadDecoder
since you did not include it in your question. So even though this code will compile, it will not actually work.Upvotes: 0