Skip to content

Shadowing as a workaround for orphans #23

Description

@mausch

I've been thinking about a workaround for orphan instances. One way would be to shadow the original inline function and add another dictionary/lookup type.

For example, say you want to use Fleece to serialize a System.Collections.Generic.HashSet<T>. This type is currently not defined in the ToJSON class in Fleece, so it would be an orphan. Here's the shadowing:

open System.Collections.Generic
open System.Json
open Fleece
open ReadOnlyCollectionsExtensions

type MyJSON = MyJSON with
    static member inline ToJSON (x: _ HashSet) =
        JArray ((Seq.map toJSON x).ToReadOnlyList())

let inline iToJSON (a: ^a, b: ^b, z: ^z) =
    ((^a or ^b or ^z) : (static member ToJSON: ^z -> JsonValue) z)
let inline toJSON x = iToJSON (ToJSONClass, MyJSON, x)

(* original definitions:
let inline iToJSON (a: ^a, z: ^z) =
    ((^a or ^z) : (static member ToJSON: ^z -> JsonValue) z)
let inline toJSON (x: 'a) : JsonValue = iToJSON (ToJSONClass, x)
*)

let set1 = HashSet [1;2;3]
let setJSON = toJSON set1
let stringJSON = toJSON "abc" // instances defined in ToJSONClass still work
printfn "%s" (setJSON.ToString())

I'm almost certain this can also be done with the FsControl convention, but surely you can figure out how faster than me :)
The obvious downsides:

  • You have to look up the original definition of the function you want to shadow.
  • You have to redefine any other functions that depend on the function you're shadowing (annoying, but otherwise things would break horribly)

Do you see any other downsides? What do you think?

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions