[RFC FS-1031] Discussion: Allow implementing the same interface at different generic instantiations in the same type #185
Replies: 11 comments
-
@dsyme Do I understand your comment correctly, that you explicitly don't want to enable the following scenario (multiple instantiations with type unknowns)? let x = { new IGet<_> with member x.Get() = 1
interface IGet<_> with member x.Get() = "hello"
interface IGet<_> with member x.Get() = 1. } I'm kind of torn, disallowing it would really simplify the implementation, but I think it would be nice to have.
ref: dotnet/fsharp#18 |
Beta Was this translation helpful? Give feedback.
-
Yes, my gut feeling was that we should require full type instantiations at these points (or else there will be trouble further down the line in processing the declarations) I may be wrong though, will look at your prototype and tests |
Beta Was this translation helpful? Give feedback.
-
I have for now updated the RFC to explicitly disallow multiple type unknowns - should we figure out that the implementation would be trivial (which I doubt ...), it can be added again. Besides, if the member implementations become slightly more complex than a single constant expression, it may be good design to explicitly state the type anyway. |
Beta Was this translation helpful? Give feedback.
-
I just noticed that the following code type IFoo<'T> = interface end
let f<'T when 'T :> IFoo<int> and 'T :> IFoo<string>>() = () fails with the type error
The error feels somewhat related to the current generic interfaces restriction. |
Beta Was this translation helpful? Give feedback.
-
It is currently possible to override an interface implementation from a base class: type IB<'a> =
interface
abstract X : unit -> int
end
type CBase() =
interface IB<int> with
member x.X() = 1
type C2() =
inherit CBase()
interface IB<int> with
member x.X() = 3 It is currently not possible to override a specific interface implementation with a generic implementation: type IB<'a> =
interface
abstract X : unit -> int
end
type CBase() =
interface IB<int> with
member x.X() = 1
type C2<'T>() =
inherit CBase()
interface IB<'T> with
member x.X() = 3
The equivalent is possible in C#: interface I<T>
{
T Get();
}
public class Base : I<int>
{
public int Get() => 1;
}
public class C<T> : Base, I<T>
{
public T Get() => default(T);
}
var c = new C<int>();
> (c as I<int>).Get()
0 This issue is not directly related to this RFC, but I found it when testing the behavior. I know that F# is not just a functional C#, so should it be considered "by-design", and a potential language suggestion, or should I move this to visualfsharp as a bugreport? What about the behavior @eiriktsarpalis found? "By design", so a new language suggestion, or bug, so a new bugreport at visualfsharp? |
Beta Was this translation helpful? Give feedback.
-
The behaviour mentioned by @eiriktsarpalis is by design. From the F# language spec (4.0)
|
Beta Was this translation helpful? Give feedback.
-
I believe all the behaviours here are currently by-design. So the suggestion can stay open here. |
Beta Was this translation helpful? Give feedback.
-
@0x53A Will it work with F# struct (value) types too? Eg.: type IA<'T> =
abstract member Get : unit -> obj
[<Struct>]
type MyStruct =
interface IA<int> with
member x.Get() = upcast 1
interface IA<string> with
member x.Get() = upcast 2 How it supposed to work / interop with default interface methods (https://github.com/dotnet/csharplang/blob/master/proposals/default-interface-methods.md) ? |
Beta Was this translation helpful? Give feedback.
-
@zpodlovics this is a pure language feature. It will not affect anything wrt default interface methods (which can be a pure CLR feature, but probably need language support to not be super annoying). Also, I see no reason why it shouldn't work with structs. |
Beta Was this translation helpful? Give feedback.
-
I just discovered this from the list of features that may make it into F# 5. I hope is does. I think this may resolve a type issue I have been struggling with. jackfoxy/DependentTypes#14 |
Beta Was this translation helpful? Give feedback.
-
This definitely gets a vote from me! I think it would be really useful to have as it increases the opportunities to use libraries written in other languages from F#. As I understand it, there is no workaround for this other than implementing in C# and reuse from F#. This was quite a surprise as it is the first time in the 4 years or so that I have been working in F# where I have encountered an interop issue that stops implementation in F#. My use case comes from is working with the Rebus .Net service bus. Anyone working with NServiceBus would also need this. Both of these libraries implement long-running, durable workflows for which I need to write something like this:
|
Beta Was this translation helpful? Give feedback.
-
Discussion for https://github.com/fsharp/fslang-design/blob/master/FSharp-5.0/FS-1031-Allow%20implementing%20the%20same%20interface%20at%20different%20generic%20instantiations%20in%20the%20same%20type.md
Beta Was this translation helpful? Give feedback.
All reactions