Fallo de herencia de la interfaz F#debido a la unidad
unit-type (1)
¿Alguien sabe por qué esto no compila?
type MyInterface<''input, ''output> =
abstract member MyFun: ''input -> ''output
type MyClass() =
interface MyInterface<string, unit> with
member this.MyFun(input: string) = ()
//fails with error FS0017: The member ''MyFun : string -> unit'' does not have the correct type to override the corresponding abstract method.
type MyUnit = MyUnit
type MyClass2() =
//success
interface MyInterface<string, MyUnit> with
member this.MyFun(input: string) = MyUnit
Esto se ve como un desagradable caso de esquina en el lenguaje F #, pero no estoy seguro si califica como una limitación por diseño o un error en el compilador. Si es por limitación de diseño, entonces el mensaje de error debería decir eso (porque actualmente, no tiene mucho sentido).
De todos modos, el problema es que el compilador F # no genera código que realmente contenga el tipo de unit
en el IL. Lo reemplaza con void
(cuando se usa como un tipo de devolución) o con lista de argumentos vacía (cuando se usa como método o argumento de función).
Esto significa que en el tipo MyClass
, el compilador decide compilar el miembro MyFun
como un método que toma string
y devuelve void
(pero no puede usar void
como argumento de tipo genérico, por lo que esto simplemente no funciona). En principio, el compilador podría usar el tipo de unit
real en este caso (porque esa es la única manera de hacerlo funcionar), pero eso probablemente crearía otras inconsistencias en otros lugares.
Tu truco para crear MyUnit
es, creo, una forma perfecta de resolver el problema. Incluso la biblioteca central F # utiliza algo como MyUnit
en algunos lugares de la implementación (en flujos de trabajo asíncronos) para tratar algunas limitaciones de la unit
(y la forma en que se compila).