Programmazione interattiva con F #

F# Interactive (dotnet fsi) viene usato per eseguire codice F# in modo interattivo nella console o per eseguire script F#. In altre parole, F# interactive esegue un repl (lettura, valutazione, ciclo di stampa) per F#.

Per eseguire F# Interactive dalla console di , eseguire dotnet fsi. È disponibile dotnet fsi in qualsiasi SDK di .NET.

Per informazioni sulle opzioni della riga di comando disponibili, vedere F# Interactive opzioni.

Esecuzione di codice direttamente in F# Interactive

Poiché F# Interactive è un ciclo REPL (read-eval-print), è possibile eseguire codice in modo interattivo. Di seguito è riportato un esempio di sessione interattiva dopo l'esecuzione dotnet fsi dalla riga di comando:

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 = ()

Si noteranno due aspetti principali:

  1. Tutto il codice deve essere terminato con un punto e virgola doppio (;;) per essere valutato
  2. Il codice viene valutato e archiviato in un it valore . È possibile fare riferimento in it modo interattivo.

F# Interactive supporta anche l'input su più righe. È sufficiente terminare l'invio con un doppio punto e virgola (;;). Si consideri il frammento di codice seguente incollato e valutato da 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 = ()

>

La formattazione del codice viene mantenuta ed è presente un doppio punto e virgola (;;) che termina l'input. F# Interactive quindi valutato il codice e stampato i risultati.

Scripting con F#

La valutazione interattiva del codice in F# Interactive può essere un ottimo strumento di apprendimento, ma si noterà rapidamente che non è produttivo quanto scrivere codice in un normale editor. Per supportare la normale modifica del codice, è possibile scrivere script F#.

Gli script usano l'estensione fsx. Anziché compilare il codice sorgente e quindi eseguire in un secondo momento l'assembly compilato, è sufficiente eseguire dotnet fsi e specificare il nome file dello script del codice sorgente F# e F# interattivo legge il codice ed esegue il codice in tempo reale. Si consideri ad esempio lo script seguente denominato Script.fsx:

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

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

Quando questo file viene creato nel computer, è possibile eseguirlo dotnet fsi con e visualizzare l'output direttamente nella finestra del terminale:

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

Lo scripting F# è supportato in modo nativo in Visual Studio, Visual Studio Code e Visual Studio per Mac.

Riferimento ai pacchetti in F# Interactive

Nota

Il sistema di gestione dei pacchetti è estendibile.

F# Interactive supporta il riferimento NuGet pacchetti con la #r "nuget:" sintassi e una versione facoltativa:

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

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

Se non viene specificata una versione, viene utilizzato il pacchetto non in anteprima più alto disponibile. Per fare riferimento a una versione specifica, introdurre la versione tramite una virgola. Questo può essere utile quando si fa riferimento a una versione di anteprima di un pacchetto. Si consideri ad esempio questo script usando una versione di anteprima di 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)}"

Specifica di un'origine del pacchetto

È anche possibile specificare un'origine del pacchetto con il #i comando . L'esempio seguente specifica un'origine remota e un'origine locale:

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

In questo modo il motore di risoluzione sotto le coperture dovrà anche prendere in considerazione le origini remote e/o locali aggiunte a uno script.

È possibile specificare il numero di riferimenti al pacchetto che si desidera in uno script.

Nota

Esiste attualmente una limitazione per gli script che usano riferimenti al framework (ad esempioMicrosoft.NET.Sdk.Web o Microsoft.NET.Sdk.WindowsDesktop). Pacchetti come Saturn, Giraffe, WinForms non sono disponibili. Questa operazione viene rilevata nel problema 9417.

Riferimento ad assembly su disco con F# interattivo

In alternativa, se si dispone di un assembly su disco e si vuole fare riferimento a tale assembly in uno script, #r è possibile usare la sintassi per specificare un assembly. Si consideri il codice seguente in un progetto compilato in MyAssembly.dll:

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

Dopo la compilazione, è possibile fare riferimento a tale file in un file denominato Script.fsx in questo modo:

#r "path/to/MyAssembly.dll"

printfn $"{MyAssembly.myFunction 10 40}"

L'output è il seguente:

dotnet fsi Script.fsx
90

È possibile specificare tutti i riferimenti ad assembly che si desiderano in uno script.

Caricamento di altri script

Quando si esegue lo scripting, spesso può essere utile usare script diversi per attività diverse. In alcuni casi può essere necessario riutilizzare il codice da uno script in un altro. Anziché copiare e incollare il contenuto nel file, è sufficiente caricarlo e valutarlo con #load.

Si consideri quanto segue Script1.fsx:

let square x = x * x

E il file di utilizzo, Script2.fsx:

#load "Script1.fsx"
open Script1

printfn $"%d{square 12}"

È possibile valutare in Script2.fsx questo modo:

dotnet fsi Script2.fsx
144

È possibile specificare tutte le #load direttive che si desiderano in uno script.

Nota

La open Script1 dichiarazione è obbligatoria. Ciò è dovuto al fatto che i costrutti in uno script F# vengono compilati in un modulo di primo livello che rappresenta il nome del file di script in cui si trova. Se il file di script ha un nome minuscolo, ad esempio , il nome del modulo implicito viene automaticamente script3.fsx in maiuscolo ed è necessario usare open Script3. Se si desidera che uno script caricabile definisse i costrutti in uno spazio dei nomi specifico del modulo, è possibile includere uno spazio dei nomi della dichiarazione del modulo, ad esempio:

module MyScriptLibrary

Uso dell'oggetto fsi nel codice F#

Gli script F# hanno accesso a un oggetto fsi personalizzato che rappresenta la F# Interactive sessione. Consente di personalizzare elementi come la formattazione dell'output. È anche possibile accedere agli argomenti della riga di comando.

L'esempio seguente illustra come ottenere e usare gli argomenti della riga di comando:

let args = fsi.CommandLineArgs

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

Quando viene valutato, stampa tutti gli argomenti. Il primo argomento è sempre il nome dello script valutato:

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

È anche possibile usare System.Environment.GetCommandLineArgs() per accedere agli stessi argomenti.

F# Interactive riferimento alla direttiva

Le #r direttive e #load viste in precedenza sono disponibili solo in F# Interactive. Sono disponibili diverse direttive solo in F# Interactive:

Direttiva Descrizione
#r "nuget:..." Fa riferimento a un pacchetto da NuGet
#r "assembly-name.dll" Fa riferimento a un assembly su disco
#load "file-name.fsx" Legge un file di origine, lo compila e lo esegue.
#help Visualizza informazioni sulle direttive disponibili.
#I Specifica un percorso di ricerca assembly tra virgolette.
#quit Termina una sessione di F# Interactive.
#time "on" o #time "off" Di per sé, #time attiva o disattiva la visualizzazione delle informazioni sulle prestazioni. Quando è "on", F# Interactive le informazioni su tempo reale, tempo CPU e Garbage Collection per ogni sezione di codice interpretata ed eseguita.

Quando si specificano file o percorsi in F# Interactive, è previsto un valore letterale di stringa. Quindi, file e percorsi devono essere racchiusi tra virgolette ed è necessario applicare i caratteri di escape consueti. È possibile usare il @ carattere per F# Interactive interpretare una stringa che contiene un percorso come stringa verbatim. In questo modo F# Interactive ignorerà i caratteri di escape.

Direttive per il preprocessore interattive e compilate

Quando si compila il codice in F# Interactive, indipendentemente dal fatto che venga eseguito in modo interattivo o in esecuzione uno script, viene definito il simbolo INTERACTIVE . Quando si compila il codice nel compilatore, viene definito il simbolo COMPILED . Pertanto, se il codice deve essere diverso nelle modalità compilate e interattive, è possibile usare queste direttive del preprocessore per la compilazione condizionale per determinare quale usare. Ad esempio:

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

Uso F# Interactive in Visual Studio

Per eseguire F# Interactive in Visual Studio, è possibile fare clic sul pulsante F# Interactive appropriato sulla barra degli strumenti oppure premere i tasti CTRL+ALT+F. Questa operazione comporterà l'apertura della finestra interattiva, una finestra degli strumenti che esegue una sessione di F# Interactive. È anche possibile selezionare il codice da eseguire nella finestra interattiva e premere la combinazione di tasti ALT+INVIO. F# Interactive viene avviato in una finestra degli strumenti denominata F# Interactive. Quando si usa questa combinazione di tasti, assicurarsi che sia selezionata la finestra dell'editor.

Sia che si utilizzi la console o Visual Studio, viene visualizzato un prompt dei comandi e l'interprete attende l'input. Immettere il codice come si farebbe in un file di codice. Per compilare ed eseguire il codice, immettere due punti e virgola (;;) per terminare una o più righe di input.

F# Interactive prova a compilare il codice e, in caso contrario, esegue il codice e stampa la firma dei tipi e dei valori compilati. Se si verificano errori, l'interprete stampa i messaggi di errore.

Il codice immesso nella stessa sessione ha accesso a qualsiasi costrutto immesso in precedenza, per consentire la compilazione di programmi. Un buffer completo nella finestra degli strumenti consente di copiare il codice in un file, se necessario.

Se eseguito in Visual Studio, F# Interactive viene eseguito in modo indipendente dal progetto. In questo modo, ad esempio, non è possibile usare costrutti definiti nel progetto in F# Interactive a meno che non sia possibile copiare il codice per la funzione nella finestra interattiva.

È possibile controllare F# Interactive argomenti della riga di comando (opzioni) modificando le impostazioni. Nel menu Strumenti selezionare Opzioni, quindi espandere Strumenti F#. Le due impostazioni che è possibile modificare sono le opzioni di F# Interactive e l'impostazione F# Interactive a 64 bit, che è rilevante solo se si esegue F# Interactive in un computer a 64 bit. Questa impostazione determina se si vuole eseguire la versione dedicata a 64 bit di fsi.exe ofsianycpu.exe, che usa l'architettura del computer per determinare se eseguire come processo a 32 bit o a 64 bit.

Titolo Descrizione
Opzioni di F# Interactive Descrive la sintassi della riga di comando e le opzioni F# Interactive, fsi.exe.