2010-12-10 9 views
11

Z F # rozumiem, że można użyć wbudowanego słowa kluczowego, aby wykonać specjalizację typu na stronie połączenia. Czyli ::Jak działa F # inline?

val inline (+) : ^a -> ^b -> ^c 
     when (^a or ^b) : (static member (+) : ^a * ^b -> ^c) 

Ogranicza że ^a lub ^b musi mieć element statyczny jak op_Addition lub jednego z wbudowanych w prymitywów, które mogą być wykorzystane do wypełnienia luki.

Więc jeśli masz metodę, która ma + i przekazujesz w int i short jako parametry, odwija ​​+ do instrukcji użycia wbudowanego prymitywu dla int, i jeśli przekazujesz float i bajt używa podstawowego kodu źródłowego operacji float.

Jak dokładnie to robi się podczas kompilacji? W jaki sposób można mieć metodę w CLR, który przełącza, jakiego kodu lub metody używa na podstawie typu?

Czy to zachowanie jest możliwe w Reflection.Emit? Rozumiem, że wpisywanie jest wykonywane w witrynie wywołania, czy to oznacza, że ​​kod nie działa z C#?

+0

Nie wiem zbyt wiele o wewnętrznych, ale wygląda na to, że kod źródłowy F # definiuje operatora '+' (C: \ Program Files (x86) \ FSharp-2.0.0.0 \ source \ fsharp \ FSharp .Core \ prim-types.fs wiersz 3527) przełącza typy argumentów w typie kompilacji i bezpośrednio wysyła kod IL. – Juliet

Odpowiedz

8

Zgodnie z sugestią użytkownika inline kod jest umieszczany na stronie połączenia. Na każdej stronie z zaproszeniem znasz konkretny parametr typu ^T, w którym wstawiany jest konkretny kod tego typu.

Wykonuje to kompilator F #, którego nie można łatwo zrobić w innym kontekście (np. C# lub Ref.Emit).

Biblioteka F # ma kilka wbudowanych funkcji, które mogą być nadal wywoływane przez inne języki, środowisko wykonawcze dla tych implementacji wykonuje dynamiczną wysyłkę w oparciu o typ środowiska wykonawczego, zobacz np. kod AdditionDynamic w kodzie biblioteki F # Core, aby się poczuć.

+0

Więc mówisz, że to po prostu skomplikowana sztuczka kompilatora? Jeśli zadzwonię do 'FSharpFunc <,>' z C# czy dostanę pożądane zachowanie? –

+2

Każde wystąpienie typu 'FSharpFunc' (lub większość typów) nie jest (i nie może) być' inline'. 'inline' odnosi się do metod i funkcji, a tylko garść z nich znajduje się w bibliotece F #. Większość rzeczy można nazwać dobrze z C#, ale kilka funkcji F # 'inline', które nie obsługują dynamicznego wywoływania (jak' sin') może być wywołane tylko z F #, ponieważ kompilator F # musi wstawiać kod w witrynie wywołania. – Brian