To wygląda bolesnego rogu literami w języku F #, ale nie jestem pewien, czy to kwalifikuje się jako ograniczenie ubocznych projektowania lub błąd w kompilator. Jeśli jest to z powodu ograniczenia projektu, komunikat o błędzie powinien to powiedzieć (ponieważ obecnie nie ma to większego sensu).
W każdym razie problemem jest to, że kompilator F # nie generuje kodu, który faktycznie zawiera typ unit
w IL. Zastępuje go void
(gdy jest używany jako typ zwracany) lub z pustą listą argumentów (gdy jest używana jako metoda lub argument funkcji).
Oznacza to, że w typie MyClass
, kompilator zdecyduje się skompilować człon MyFun
jako metody, które odbywają string
i powraca void
(ale nie można używać void
jako ogólny typ argumentu, więc to po prostu nie działa). Zasadniczo kompilator może używać rzeczywistego typu unit
w tym przypadku (ponieważ jest to jedyny sposób, aby to działało), ale prawdopodobnie spowoduje to inne niespójności w innym miejscu.
Twoja sztuczka polegająca na tworzeniu MyUnit
jest, moim zdaniem, doskonałym sposobem na rozwiązanie problemu. Nawet podstawowa biblioteka F # używa czegoś takiego jak MyUnit
w niektórych miejscach implementacji (w asynchronicznych przepływach pracy), aby poradzić sobie z pewnymi ograniczeniami związanymi z unit
(i sposobem, w jaki jest kompilowany).
Dzięki Tomas. Nie widziałem tego problemu gdzie indziej (np. W normalnych funkcjach z let;) –
@Stefan: Jeśli użyjesz argumentu 'unit' jako argumentu (do funkcji lub typu), to ogólnie jest w porządku. Ten błąd/ograniczenie prawdopodobnie pojawia się tylko podczas implementowania abstrakcyjnych elementów (co jest nieco trudnym obszarem dla kompilatora F #, ponieważ dziedziczenie jest zaskakująco skomplikowane w .NET). –
Co ciekawe, będzie działać w języku C# i będę mógł korzystać z funkcji w F #. Prawdopodobnie powinien zostać zgłoszony jako błąd. –