I suggest we ...

Allow inheritance from .NET types that implement the same interface at different generic instantiations

60 votes
Vote
Sign in
(thinking…)
Sign in with: facebook google
Signed in as (Sign out)
You have left! (?) (thinking…)
Gustavo Guerra shared this idea  ·   ·  Flag idea as inappropriate…  ·  Admin →

This has been completed for F# 4.0+

The user voice suggestion has been renamed to reflect the feature implemented – “Allow inheritance from .NET types that implement the same interface at different generic instantiations”

The overall status for F# 4.0 is at https://github.com/Microsoft/visualfsharp/wiki/F%23-4.0-Status

Don Syme, F# Language Evolution

8 comments

Sign in
(thinking…)
Sign in with: facebook google
Signed in as (Sign out)
Submitting...
  • Abel commented  ·   ·  Flag as inappropriate

    Looks like the implementation of this is broken in VS 2015, or at least it works differently now. Generic implementations with different type parameters are still not possible (which is what the user suggested), and calling such an implementation from a .NET library leads to different results between F# 3 and 4.

    See: http://fslang.uservoice.com/forums/245727-f-language/suggestions/5663504-allow-to-implement-the-same-interface-at-different, titled "Difference between treatment of ambiguous generic interfaces by F# between VS 2012 and VS 2015 leading to compile errors in the latter"

  • exercitus vir commented  ·   ·  Flag as inappropriate

    I still don't like the restricted version, but the notes (copied from the contribution) are interesting, especially the workaround:

    "Note, the change still keeps the restriction that an F# type can itself only implement one instantiation of a generic interface type. For example

    type C() =
    interface I<int>
    interface I<string>

    is not allowed. This is partly because of the way interface implementation methods are named in compiled IL (only the prefix "I" is added), and partly because the equivalent object expression form can inculde type unknowns, e.g.

    { interface I<_> with ...
    interface I<_> with ...

    and we don't want to support this kind of inference, and equally don't want a non-orthogonality between object expressions and class definitions. As a workaround you can always add an extra inherit each type you wish to introduce new interface instantiations, e.g.

    type C() =
    interface I<int> with ...

    type D() =
    inherit C()
    interface I<string> with ...
    "

  • exercitus vir commented  ·   ·  Flag as inappropriate

    Not fully implementing this feature as in C# makes it rather useless. You must be able to use I<T> and I<U> as interface constraints in F# if I is a generic interface and T and U are type parameters. The following assumption should be dropped from the compiler: _if a type is constrained by both I and I then T = U_

    Like Maciej said, this is going to cause problems in any case.

  • Maciej J. Bańkowski commented  ·   ·  Flag as inappropriate

    Don, correct me if I am wrong but the statement
    IF type constrained by I < T > and I < U > THEN T = U is simply false and hence is bound to cause problems down the line.

    Can this whole assumption be dropped from the compiler?

  • Don Syme commented  ·   ·  Flag as inappropriate

    The main problem is an interaction with type inference, where F# makes the assumption that if a type is constrained by both I < T > and I < U > then T = U.

    This means it will be likely that there is an ongoing limitation that a type variable can’t be constrained by multiple interface instantiations. However that’s a much weaker restriction than the current one.

  • Aaron Bockover commented  ·   ·  Flag as inappropriate

    We ran into this with a type written in C# implementing multiple IObservable<T> interfaces. Fortunately we were able to change that API design on the C# time by the time we realized we were hosed on the F# side. This would be incredibly useful to support in F#.

  • Jack Pappas commented  ·   ·  Flag as inappropriate

    I've run into this a few times. I understand it may be a difficult feature to implement due to type inference (see Brian's answer to the linked StackOverflow question); but as Andrew said, it can be a show-stopping issue when you want to convert an existing C# library to F# but the public API can't be changed.

  • Andrew Khmylov commented  ·   ·  Flag as inappropriate

    Looks like a quite important feature to me.
    We have a fairly sophisticated C# code base which encodes a lot of business rules in type system and heavily uses multiple interface implementations with various type parameters. Converting it to F# is not possible at the moment due to this compiler restriction.

F# Language

Feedback and Knowledge Base