f# unit-type

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).