7

Consider this interface:

type A<'a> =
    abstract X : 'a

Let's try to implement it with int as a generic argument:

{ new A<int> with member this.X = 5 } // all is well

Now, let's try unit for an argument:

// Compiler error: The member 'get_X : unit -> unit' does not have the correct type to override the corresponding abstract method.
{ new A<unit> with member this.X = () }

Now, if we define a non-generic interface, everything also works well:

type A_int =
    abstract X : int

{ new A_int with member this.X = 5 } // works

type A_unit =
    abstract X : unit

{ new A_unit with member this.X = () } // works as well!

Is there anything I can do to fix this problem?

Guy Coder
  • 24,501
  • 8
  • 71
  • 136
MisterMetaphor
  • 5,900
  • 3
  • 24
  • 31
  • In C# it is not possible to have a generic function returning `void` - see for example https://programmers.stackexchange.com/questions/131036/why-is-void-not-allowed-as-a-generic-type-in-c . It is possible that similar restrictions are being applied to the F# code in this instance. – John Palmer Oct 10 '14 at 11:40

2 Answers2

5

In F#, an abstract slot with declared return type of unit gets compiled in .NET IL as a return type of void. In contrast, an abstract slot with declared return type of "T" gets compiled in .NET IL as a generic return type of "T", which when T is instantiated by unit becomes unit'.

See : F# interface inheritance failure due to unit

Community
  • 1
  • 1
ArthurCPPCLI
  • 1,072
  • 7
  • 18
0

Your generic member X can be a value of any type. 'unit' in F# is not really a type (or is very special type if you wish) - it's an absence of any value.

Petr
  • 4,280
  • 1
  • 19
  • 15