Brian Berns
Brian Berns

Reputation: 17038

Creating an F# object with a generic member

In F#, I have defined an interface with a generic member:

type MyType =
    abstract MyMember<'a> : 'a -> int

I would like to write a function that can create an object that implements this interface:

module MyType =

    let create f =
        {
            new MyType with
                member __.MyMember(x) = f x
        }

This currently fails to compile with the following error message:

This code is not sufficiently generic. The type variable 'a could not be generalized because it would escape its scope.

Is it possible to make this work via inlining and static resolved type parameters (or something similar)? Thanks.

Upvotes: 2

Views: 208

Answers (1)

Asti
Asti

Reputation: 12667

An explanation for the compile error:

Object expressions construct anonymous classes - these are just regular classes, with a compiler generated name. You're essentially creating a closure which captures f.

This is how you'd normally implement it:

type MyType =
    abstract MyMember<'a> : 'a -> int

type MyNewType (f) =
    interface MyType with
        member _.MyMember x = f x

The type's constructor would have a parameter f of type 'a -> int, where 'a would normally be decided by the first usage of MyNewType.

But there's no way to generalize f such that it could be captured as a value that would satisfy the generic constraint of MyMember. Here sufficiently generic means a type of one order above the generic type.

Upvotes: 1

Related Questions