[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.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
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