Pregunta

¿Alguien sabe por qué esto falla al compilar?

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
¿Fue útil?

Solución

Esto parece una esquina desagradable caso en el idioma # F, pero no estoy seguro de si se califica como una limitación de trazado o un error en el compilador. Si es por limitación de diseño, a continuación, el mensaje de error debería decir que (ya que de momento, no tiene mucho sentido).

De todos modos, el problema es que el F # compilador no genera código que realmente contiene el tipo unit en el IL. Se reemplaza con void (cuando se usa como un tipo de retorno) o con la lista de argumentos vacía (cuando se usa como argumento de un método o función).

Esto significa que en el tipo MyClass, el compilador decide compilar el miembro de MyFun como un método que toma string y vuelve void (pero no se puede utilizar void como un argumento de tipo genérico, por lo que este simplemente no funciona). En principio, el compilador podría utilizar 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 otro lugar.

Su truco con la creación de MyUnit es, creo, una forma perfectamente bien para resolver el problema. Incluso el núcleo usos F # biblioteca algo así como MyUnit en algunos lugares de la aplicación (en flujos de trabajo asíncrono) para hacer frente a algunas limitaciones de unit (y la forma en que se compila).

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top