Udostępnij za pośrednictwem


Programowanie interakcyjne za pomocą języka F#

F# Interactive (dotnet fsi) służy do interaktywnego uruchamiania kodu F# w konsoli lub wykonywania skryptów języka F#. Innymi słowy, interaktywne środowisko F# uruchamia REPL (Odczyt, Ocena, Pętla Drukowania) dla języka F#.

Aby uruchomić program F# Interactive z poziomu konsoli programu , uruchom polecenie dotnet fsi. dotnet fsi znajdziesz w dowolnym zestawie SDK platformy .NET.

Notatka

Jeśli zamierzasz używać języka F# w środowisku uruchomieniowym programu .NET Framework, musisz narzędzia Visual Studio Build Tools lub zainstalowaną edycję programu Visual Studio i wywołać polecenie FsiAnyCPU.exe z wiersza polecenia "Developer Command Prompt" lub po prostu udostępnić FsiAnyCPU.exe w zmiennej środowiskowej PATH zamiast wiersza polecenia dotnet fsi.

Narzędzia obsługują definiowanie wersji środowiska uruchomieniowego F# Interactive:

  • W programie Visual Studio: na pasku menu Tools / Options następnie F# Tools / F# Interactivei dostosuj Użyj skryptów platformy .NET Core.
  • W programie Visual Studio Code (rozszerzenie ionide): w palecie poleceń Preferencje: Otwórz ustawienia użytkownika, a następnie Rozszerzenia / F# / FSharp: Ścieżka pliku Fsi Sdk.

Aby uzyskać informacje o dostępnych opcjach wiersza polecenia, zobacz Opcje interaktywne F#.

Wykonywanie kodu bezpośrednio w języku F# Interactive

Ponieważ F# Interactive jest interaktywną pętlą REPL (czytaj, ewaluuj, wypisuj), możesz w niej wykonywać kod w trybie interaktywnym. Oto przykład sesji interaktywnej po wykonaniu dotnet fsi z wiersza polecenia:

Microsoft (R) F# Interactive version 11.0.0.0 for F# 5.0
Copyright (c) Microsoft Corporation. All Rights Reserved.

For help type #help;;

> let square x = x *  x;;
val square : x:int -> int

> square 12;;
val it : int = 144

> printfn "Hello, FSI!"
- ;;
Hello, FSI!
val it : unit = ()

Zauważysz dwie główne kwestie:

  1. Cały kod musi zostać zakończony podwójnym średnikiem (;;), aby można go było ocenić
  2. Kod jest obliczany i przechowywany w wartości it. Możesz odwoływać się do it interaktywnie.

F# Interactive obsługuje również wprowadzanie wielowierszowe. Wystarczy zakończyć swoje zgłoszenie podwójnym średnikiem (;;). Rozważ następujący fragment kodu, który został wklejony i oceniony przez aplikację F# Interactive:

> let getOddSquares xs =
-     xs
-     |> List.filter (fun x -> x % 2 <> 0)
-     |> List.map (fun x -> x * x)
-
- printfn "%A" (getOddSquares [1..10]);;
[1; 9; 25; 49; 81]
val getOddSquares : xs:int list -> int list
val it : unit = ()

>

Formatowanie kodu jest zachowywane i występuje podwójny średnik (;;) kończący dane wejściowe. F# Interactive następnie ocenił kod i wydrukował wyniki!

Wykonywanie skryptów za pomocą języka F#

Interaktywne ocenianie kodu w języku F# Interactive może być doskonałym narzędziem do uczenia się, ale szybko okaże się, że nie jest to tak wydajne, jak pisanie kodu w normalnym edytorze. Aby obsługiwać normalne edytowanie kodu, możesz pisać skrypty języka F#.

Skrypty używają rozszerzenia pliku .fsx. Zamiast kompilować kod źródłowy, a następnie później uruchamiać skompilowany zestaw, wystarczy uruchomić dotnet fsi i określić nazwę pliku skryptu kodu źródłowego języka F#, a język F# interakcyjny odczytuje kod i wykonuje go w czasie rzeczywistym. Rozważmy na przykład następujący skrypt o nazwie Script.fsx:

let getOddSquares xs =
    xs
    |> List.filter (fun x -> x % 2 <> 0)
    |> List.map (fun x -> x * x)

printfn "%A" (getOddSquares [1..10])

Po utworzeniu tego pliku na maszynie możesz uruchomić go za pomocą dotnet fsi i wyświetlić dane wyjściowe bezpośrednio w oknie terminalu:

dotnet fsi Script.fsx
[1; 9; 25; 49; 81]

Skrypty języka F# są natywnie obsługiwane w programach Visual Studio i Visual Studio Code.

Odwoływanie się do pakietów w języku F# Interactive

Notatka

System zarządzania pakietami jest rozszerzalny, zobacz więcej na temat wtyczek i mechanizmu rozszerzenia.

Od wersji 5.0 języka język F# Interactive obsługuje odwoływanie się do pakietów za pomocą mechanizmu rozszerzalności; można odwoływać się do pakietów NuGet za pomocą składni #r "nuget:" i opcjonalnej wersji:

#r "nuget: Newtonsoft.Json"
open Newtonsoft.Json

let data = {| Name = "Don Syme"; Occupation = "F# Creator" |}
JsonConvert.SerializeObject(data)

Jeśli nie określono wersji, zostanie pobrany najwyższy dostępny pakiet bez wersji zapoznawczej. Aby odwołać się do określonej wersji, wprowadź wersję za pośrednictwem przecinka. Może to być przydatne podczas odwoływania się do wersji zapoznawczej pakietu. Rozważmy na przykład użycie tego skryptu w wersji zapoznawczej DiffSharp:

#r "nuget: DiffSharp-lite, 1.0.0-preview-328097867"
open DiffSharp

// A 1D tensor
let t1 = dsharp.tensor [ 0.0 .. 0.2 .. 1.0 ]

// A 2x2 tensor
let t2 = dsharp.tensor [ [ 0; 1 ]; [ 2; 2 ] ]

// Define a scalar-to-scalar function
let f (x: Tensor) = sin (sqrt x)

printfn $"{f (dsharp.tensor 1.2)}"

Określanie źródła pakietu

Możesz również określić źródło pakietu za pomocą polecenia #i. Poniższy przykład określa zdalne i lokalne źródło:

#i "nuget: https://my-remote-package-source/index.json"
#i """nuget: C:\path\to\my\local\source"""

Spowoduje to, że mechanizm rozpoznawczy w tle weźmie pod uwagę również zdalne i/lub lokalne źródła dodane do skryptu.

Możesz określić dowolną liczbę odwołań do pakietu w skryscie.

Notatka

Obecnie istnieje ograniczenie dotyczące skryptów korzystających z odwołań do platform (np.Microsoft.NET.Sdk.Web lub Microsoft.NET.Sdk.WindowsDesktop). Pakiety takie jak Saturn, Giraffe, WinForms nie są dostępne. Jest to śledzone w zgłoszeniu #9417. Narzędzia WinForms nadal działają w wersji .NET Framework języka F# Interactive.

Aby załadować dodatkowe rozszerzenia obok tych dostarczanych z zestawem SDK i/lub z narzędziami, użyj flagi --compilertool:<extensionsfolderpath> jako argumentu dla sesji interaktywnej języka F# (lub w ustawieniach narzędzi).

Odwoływanie się do zestawów na dysku za pomocą interaktywnego języka F#

Alternatywnie, jeśli masz zestaw na dysku i chcesz odwołać się do tego w skryscie, możesz użyć składni #r do określenia zestawu. Rozważ następujący kod w projekcie skompilowanym w MyAssembly.dll:

// MyAssembly.fs
module MyAssembly
let myFunction x y = x + 2 * y

Po skompilowaniu można odwoływać się do niego w pliku o nazwie Script.fsx w następujący sposób:

#r "path/to/MyAssembly.dll"

printfn $"{MyAssembly.myFunction 10 40}"

Dane wyjściowe są następujące:

dotnet fsi Script.fsx
90

Możesz określić dowolną liczbę odwołań do zestawów w skrypcie.

Ładowanie innych skryptów

Podczas wykonywania skryptów często warto używać różnych skryptów do różnych zadań. Czasami możesz chcieć ponownie użyć kodu z jednego skryptu w innym. Zamiast kopiować jego zawartość do pliku, możesz po prostu załadować ją i ocenić za pomocą #load.

Rozważ następujące Script1.fsx:

let square x = x * x

A konsumujący plik, Script2.fsx:

#load "Script1.fsx"
open Script1

printfn $"%d{square 12}"

Możesz ocenić Script2.fsx w następujący sposób:

dotnet fsi Script2.fsx
144

Można określić dowolną liczbę dyrektyw #load w skrypcie.

Notatka

Wymagana jest deklaracja open Script1. Dzieje się tak dlatego, że konstrukcje w skryfcie języka F# są kompilowane w module najwyższego poziomu, który jest nazwą pliku skryptu, w którego się znajduje. Jeśli plik skryptu ma nazwę z małych liter, taką jak script3.fsx, to dorozumiana nazwa modułu jest automatycznie kapitalizowana i należy użyć open Script3. Jeśli chcesz, aby skrypt ładowalny mógł definiować konstrukcje w określonej przestrzeni nazw modułu, możesz dołączyć przestrzeń nazw deklaracji modułu, na przykład:

module MyScriptLibrary

Używanie obiektu fsi w kodzie języka F#

Skrypty języka F# mają dostęp do niestandardowego obiektu fsi, który reprezentuje sesję interaktywną języka F#. Umożliwia dostosowanie elementów, takich jak formatowanie danych wyjściowych. Jest to również sposób uzyskiwania dostępu do argumentów wiersza polecenia.

W poniższym przykładzie pokazano, jak uzyskać argumenty wiersza polecenia i używać ich:

let args = fsi.CommandLineArgs

for arg in args do
    printfn $"{arg}"

Podczas oceniania wyświetla wszystkie argumenty. Pierwszy argument jest zawsze nazwą skryptu, który jest oceniany:

dotnet fsi Script1.fsx hello world from fsi
Script1.fsx
hello
world
from
fsi

Możesz również użyć System.Environment.GetCommandLineArgs(), aby uzyskać dostęp do tych samych argumentów.

Odwołanie do dyrektyw interakcyjnych programu F#

Dyrektywy #r i #load widoczne wcześniej są dostępne tylko w języku F# Interactive. Istnieje kilka dyrektyw dostępnych tylko w języku F# Interactive:

Dyrektywa Opis
#r "nuget:..." Odwołuje się do pakietu NuGet
#r "extname:..." Odwołanie do pakietu z rozszerzenia extname[^1] (na przykład paket)
#r "assembly-name.dll" Odwołuje się do zestawu na dysku
#load "file-name.fsx" Odczytuje plik źródłowy, kompiluje go i uruchamia.
#help Przedstawia informacje o dostępnych dyrektywach lub dokumentacji dla określonych funkcji.
#I Określa ścieżkę wyszukiwania zestawu zawartą w cudzysłowie.
#quit Kończy sesję F# Interactive.
#time on lub #time off Samo #time przełącza wyświetlanie informacji o wydajności. Kiedy wartość wynosi on, F# Interactive mierzy informacje o czasie rzeczywistym, czasie CPU i odzyskiwaniu pamięci dla każdej sekcji kodu, która jest interpretowana i wykonywana.

[^1]: Więcej informacji o rozszerzeniach interaktywnych języka F# .

Podczas określania plików lub ścieżek w języku F# Interactive oczekiwany jest literał ciągu znaków. W związku z tym pliki i ścieżki muszą znajdować się w cudzysłowie, a zwykłe znaki ucieczki mają zastosowanie. Możesz użyć znaku @, aby element F# Interactive interpretował ciąg zawierający ścieżkę jako ciąg dosłowny. Powoduje to, że F# Interactive ignoruje wszystkie znaki ucieczki.

W innych przypadkach cudzysłowy są opcjonalne, począwszy od F# 9.

Rozszerzona dyrektywa #help

Dyrektywa #help obsługuje teraz wyświetlanie dokumentacji dla określonych funkcji. Możesz przekazać nazwę funkcji bezpośrednio, aby pobrać szczegóły.

#help List.map;;

Dane wyjściowe są następujące:

Description:
Builds a new collection whose elements are the results of applying the given function
to each of the elements of the collection.

Parameters:
- mapping: The function to transform elements from the input list.
- list: The input list.

Returns:
The list of transformed elements.

Examples:
let inputs = [ "a"; "bbb"; "cc" ]

inputs |> List.map (fun x -> x.Length)
// Evaluates to [ 1; 3; 2 ]

Full name: Microsoft.FSharp.Collections.ListModule.map
Assembly: FSharp.Core.dll

To ulepszenie ułatwia interaktywne eksplorowanie i poznawanie bibliotek języka F#.

Aby uzyskać więcej informacji, zapoznaj się z oficjalnym devblog.

Interaktywne i skompilowane dyrektywy preprocesora

Podczas kompilowania kodu w F# Interactive, niezależnie od tego, czy uruchamiasz go interaktywnie, czy jako skrypt, zdefiniowany jest symbol INTERACTIVE. Podczas kompilowania kodu w kompilatorze zdefiniowany jest symbol COMPILED. W związku z tym, jeśli kod musi być inny w trybach kompilowanych i interaktywnych, można użyć tych dyrektyw preprocesora do kompilacji warunkowej, aby określić, które z nich użyć. Na przykład:

#if INTERACTIVE
// Some code that executes only in FSI
// ...
#endif

Używanie języka F# Interactive w programie Visual Studio

Aby uruchomić program F# Interactive za pomocą programu Visual Studio, możesz kliknąć odpowiedni przycisk paska narzędzi z etykietą F# Interactivelub użyć Ctrl+Alt+F. Spowoduje to otwarcie okna interaktywnego— okna narzędzia z uruchomioną sesją interaktywną języka F#. Możesz również wybrać kod, który chcesz uruchomić w oknie interaktywnym i nacisnąć kombinację Alt+Enter. Środowisko F# Interactive uruchamia się w oknie narzędzi z nazwą F# Interactive. Jeśli używasz tej kombinacji, upewnij się, że okno edytora ma fokus.

Niezależnie od tego, czy używasz konsoli, czy programu Visual Studio, zostanie wyświetlony wiersz polecenia, a interpreter oczekuje na dane wejściowe. Możesz wprowadzić kod tak samo jak w pliku kodu. Aby skompilować i wykonać kod, wprowadź dwa średniki (;;), aby zakończyć wiersz lub kilka wierszy danych wejściowych.

F# Interactive próbuje skompilować kod i, jeśli się powiedzie, wykonuje kod i drukuje podpis typów i wartości, które zostały skompilowane. Jeśli wystąpią błędy, interpreter wyświetla komunikaty o błędach.

Kod wprowadzony w tej samej sesji ma dostęp do wszystkich wprowadzonych wcześniej konstrukcji, dzięki czemu można tworzyć programy. Rozbudowany bufor w oknie narzędzi umożliwia skopiowanie kodu do pliku w razie potrzeby.

Po uruchomieniu w programie Visual Studio program F# Interactive działa niezależnie od projektu, więc na przykład nie można używać konstrukcji zdefiniowanych w projekcie w języku F# Interactive, chyba że skopiujesz kod funkcji do okna interaktywnego.

Interakcyjne argumenty wiersza polecenia języka F# (opcje) można kontrolować, dostosowując ustawienia. W menu Narzędzia wybierz opcje ..., a następnie rozwiń narzędzia F#. Dwa ustawienia, które można zmienić, to opcje interaktywne języka F# i 64-bitowe ustawienie interaktywnego języka F#, które jest istotne tylko wtedy, gdy używasz programu F# Interactive na maszynie 64-bitowej. To ustawienie określa, czy chcesz uruchomić dedykowaną 64-bitową wersję fsi.exe, czy fsianycpu.exe, która używa architektury maszyny do określenia, czy uruchomić jako proces 32-bitowy, czy 64-bitowy.

Tytuł Opis
Interaktywne opcje F# Opisuje składnię wiersza polecenia i opcje dla języka F# Interactive, fsi.exe.